XSLT预先将节点重复为平面

Tyc*_*cho 2 xslt biztalk

我有一个XML模式,我需要从中提取值,但我没有太多运气.

源模式是:

<Reading>
   <State>
      <StateValues>
         <Name>
         <Value>
      </StateValues>
   </State>
<Reading>
Run Code Online (Sandbox Code Playgroud)

XML的一个例子是:

<Reading>
   <State>
      <StateValues>
         <Name>Reading1</Name>
         <Value>1234</Value>
      </StateValues>
      <StateValues>
         <Name>Reading2</Name>
         <Value>2345</Value>
      </StateValues>
   </State>
   <State>
      <StateValues>
         <Name>Reading3</Name>
         <Value>4321</Value>
      </StateValues>
   </State>
<Reading>
Run Code Online (Sandbox Code Playgroud)

我需要一个结果:

<Readings>
  <Reading1>1234</Reading1>
  <Reading2>2345</Reading2>
  <Reading3>4321</Reading3>
</Readings>
Run Code Online (Sandbox Code Playgroud)

我无法控制模式.

我一直在试图用一个xsl:foreachxsl:if该检查的名字,但我刚刚得到的第一个值重复3次.有小费吗?我一直试图解决这个问题2天,我不是XSLT专家......

谢谢.编辑:抱歉没有发布我的XSLT.我曾尝试过多个版本,并认为它不会有用.这里是:

大段引用

<xsl:element name="ns0:Readings">
   <xsl:element name="ns0:Current">
         <xsl:for-each select="/*[local-name()='gatewayInterface' and namespace-uri()='http://biztalk.gateway.com']/*[local-name()='Reading' and namespace-uri()='http://biztalk.gateway.com']/*[local-name()='State' and namespace-uri()='http://biztalk.gateway.com']/*[local-name()='StateValues' and namespace-uri()='http://biztalk.gateway.com']">               
            <xsl:choose>
               <xsl:when test="Name='TOTAL'">
            <xsl:element name="ns0:Total">
                <xsl:value-of select="/*[local-name()='gatewayInterface' and namespace-uri()='http://biztalk.gateway.com']/*[local-name()='Reading' and namespace-uri()='http://biztalk.gateway.com']/*[local-name()='State' and namespace-uri()='http://biztalk.gateway.com']/*[local-name()='StateValues' and namespace-uri()='http://biztalk.gateway.com']/*[local-name()='Name' and namespace-uri()='http://biztalk.gateway.com']/text()='Total'" />
            </xsl:element>
           </xsl:when>
        </xsl:choose>
        <xsl:choose>
           <xsl:when test="/*[local-name()='gatewayInterface' and namespace-uri()='http://biztalk.gateway.com']/*[local-name()='Reading' and namespace-uri()='http://biztalk.gateway.com']/*[local-name()='State' and namespace-uri()='http://biztalk.gateway.com']/*[local-name()='StateValues' and namespace-uri()='http://biztalk.gateway.com']/*[local-name()='Name' and namespace-uri()='http://biztalk.gateway.com']/text()='Reading1'">
        <xsl:element name="ns0:Reading1">
            <xsl:value-of select="/*[local-name()='gatewayInterface' and namespace-uri()='http://biztalk.gateway.com']/*[local-name()='Reading' and namespace-uri()='http://biztalk.gateway.com']/*[local-name()='State' and namespace-uri()='http://biztalk.gateway.com']/*[local-name()='StateValues' and namespace-uri()='http://biztalk.gateway.com']/*[local-name()='Name' and namespace-uri()='http://biztalk.gateway.com']/text()" />
            </xsl:element>
           </xsl:when>
        </xsl:choose>
        <xsl:choose>
           <xsl:when test="/*[local-name()='gatewayInterface' and namespace-uri()='http://biztalk.gateway.com']/*[local-name()='Reading' and namespace-uri()='http://biztalk.gateway.com']/*[local-name()='State' and namespace-uri()='http://biztalk.gateway.com']/*[local-name()='StateValues' and namespace-uri()='http://biztalk.gateway.com']/*[local-name()='Name' and namespace-uri()='http://biztalk.gateway.com']/text() = 'Reading2'">
        <xsl:element name="ns0:Reading2">
            <xsl:value-of select="/*[local-name()='gatewayInterface' and namespace-uri()='http://biztalk.gateway.com']/*[local-name()='Reading' and namespace-uri()='http://biztalk.gateway.com']/*[local-name()='State' and namespace-uri()='http://biztalk.gateway.com']/*[local-name()='StateValues' and namespace-uri()='http://biztalk.gateway.com']/*[local-name()='Name' and namespace-uri()='http://biztalk.gateway.com']/text()" />
            </xsl:element>
           </xsl:when>
        </xsl:choose>
        <xsl:choose>
           <xsl:when test="/*[local-name()='gatewayInterface' and namespace-uri()='http://biztalk.gateway.com']/*[local-name()='Reading' and namespace-uri()='http://biztalk.gateway.com']/*[local-name()='State' and namespace-uri()='http://biztalk.gateway.com']/*[local-name()='StateValues' and namespace-uri()='http://biztalk.gateway.com']/*[local-name()='Name' and namespace-uri()='http://biztalk.gateway.com']/text() = 'Reading3'">
        <xsl:element name="ns0:Reading3">
            <xsl:value-of select="/*[local-name()='gatewayInterface' and namespace-uri()='http://biztalk.gateway.com']/*[local-name()='Reading' and namespace-uri()='http://biztalk.gateway.com']/*[local-name()='State' and namespace-uri()='http://biztalk.gateway.com']/*[local-name()='StateValues' and namespace-uri()='http://biztalk.gateway.com']/*[local-name()='Name' and namespace-uri()='http://biztalk.gateway.com']/text()" />
            </xsl:element>
           </xsl:when>
        </xsl:choose>
        <xsl:choose>
           <xsl:when test="/*[local-name()='gatewayInterface' and namespace-uri()='http://biztalk.gateway.com']/*[local-name()='Reading' and namespace-uri()='http://biztalk.gateway.com']/*[local-name()='State' and namespace-uri()='http://biztalk.gateway.com']/*[local-name()='StateValues' and namespace-uri()='http://biztalk.gateway.com']/*[local-name()='Name' and namespace-uri()='http://biztalk.gateway.com']/text() = 'Reading4'">
        <xsl:element name="ns0:Reading4">
            <xsl:value-of select="/*[local-name()='gatewayInterface' and namespace-uri()='http://biztalk.gateway.com']/*[local-name()='Reading' and namespace-uri()='http://biztalk.gateway.com']/*[local-name()='State' and namespace-uri()='http://biztalk.gateway.com']/*[local-name()='StateValues' and namespace-uri()='http://biztalk.gateway.com']/*[local-name()='Name' and namespace-uri()='http://biztalk.gateway.com']/text()" />
            </xsl:element>
           </xsl:when>
        </xsl:choose>
     </xsl:for-each>
   </xsl:element>
</xsl:element>
Run Code Online (Sandbox Code Playgroud)

Ric*_*ard 5

foreach并且if通常是XSLT中的错误方法.将模板应用于模式会更有效.在这种情况下,您可以使用两个:第一个设置根元素并匹配您要使用的元素:

<xsl:template match='/'>
  <Readings>
    <xsl:apply-templates select='Reading/State/StateValues'/>
  </Readings>
</xsl:template>
Run Code Online (Sandbox Code Playgroud)

并且当找到将进行核心工作的匹配时,上述触发.这里的复杂性是动态创建一个元素,这意味着使用{XPath}语法从输入文档中获取名称:

<xsl:template match='StateValues'>
  <xsl:element name='{Name}'>
    <xsl:value-of select='Value' />
  </xsl:element>
</xsl:template>
Run Code Online (Sandbox Code Playgroud)