XSLT匹配基于连接两个节点值

时间:2013-04-14 02:25:11

标签: xslt

如果我的xml看起来像这样

<Msg>
    <Payload role="s">
       <row>
         <venue>XDM</venue>
         <account>60190</account>
       </row>
    </Payload>
    <Payload role="c" id="atom1">
      <ResultSet>
         <Row>
            <U_LegAcc>XDM60190</U_LegAcc>
            <U_AccCod>SYS00000000508</U_AccCod>
         </Row>
      </ResultSet>
    </Payload>
</Msg>

我需要根据U_LegAcc获取U_AccCod节点值,该值与场地(XDM)和&amp;的连接值相匹配。帐户(61090),即XDM61090

如何获得看起来像这样的xml。

<Msg>
  <Payload>
   <row>
     <venue>XDM</venue>
     <account>60190</account>
     <U_AccCod>SYS00000000508</U_AccCod>
   </row>
 </Payload>
</Msg>

我已经尝试过简化它并删除连接只是为了开始,但我甚至无法让它工作,即<account><U_AccCod>是相同的。我尝试过使用密钥,但我没有得到任何输出

<xsl:key name="sapaccount" match="ResultSet" use="U_LegAcc" />

<xsl:template match="Row" mode="name">
   <xsl:value-of select="U_AccCod" />
</xsl:template>

<xsl:template match="row/account">
   <xsl:apply-templates select="key('sapaccount', .)" mode="name" />
</xsl:template>

2 个答案:

答案 0 :(得分:1)

实际上没有理由不能继续使用此处的密钥。它们通常更有效地用于查找元素。您当前密钥的问题是不太正确。您目前正在通过ResultSet值查找U_LegAcc元素,但U_LegAcc不是ResultSet的直接子项,而是Row的直接子项,因此您可能想要像这样定义你的密钥:

<xsl:key name="sapaccount" match="ResultSet/Row" use="U_LegAcc" />

或者只是这个,如果Row元素只能在一个地方出现

<xsl:key name="sapaccount" match="Row" use="U_LegAcc" />

然后,要查找该值,如果位于account元素上,您可以这样做:

<xsl:apply-templates select="key('sapaccount', concat(preceding-sibling::venue, .))" />

或者更好的是,有一个模板来匹配row元素,然后你可以这样做

<xsl:apply-templates select="key('sapaccount', concat(venue, account))" />

试试这个XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   <xsl:output method="xml" indent="yes"/>

   <xsl:key name="sapaccount" match="Row" use="U_LegAcc"/>

   <xsl:template match="Payload[@role='s']">
      <Payload>
         <xsl:apply-templates/>
      </Payload>
   </xsl:template>

   <xsl:template match="Payload[@role='c']"/>

   <xsl:template match="row">
      <row>
         <xsl:apply-templates/>
         <xsl:apply-templates select="key('sapaccount', concat(venue, account))/U_AccCod"/>
      </row>
   </xsl:template>

   <xsl:template match="@*|node()">
      <xsl:copy>
         <xsl:apply-templates select="@*|node()"/>
      </xsl:copy>
   </xsl:template>
</xsl:stylesheet>

应用于XML时,输出以下内容

<Msg>
   <Payload>
      <row>
         <venue>XDM</venue>
         <account>60190</account>
         <U_AccCod>SYS00000000508</U_AccCod>
      </row>
   </Payload>
</Msg>

答案 1 :(得分:0)

在XSL中从输入中的同一元素发出row元素的部分:

<xsl:template match="row">
    <row>
        <xsl:copy-of select="venue"/>
        <xsl:copy-of select="account"/>
        <U_AccCod>
            <xsl:variable name="this" select="."/>
            <xsl:value-of select="/Msg/Payload/ResultSet/Row/U_AccCod[../U_LegAcc=concat($this/venue,$this/account)]"/>
        </U_AccCod>
    </row>
</xsl:template>

未经测试,可能需要调整。