XSLT'值'选择'在不同级别的多个属性检查

时间:2015-03-04 09:15:54

标签: xml xslt xslt-1.0

这是我面临的问题的简化Xml示例。我必须通过匹配Class&amp;来设置输出xml中的属性NameID值。 SRNo<Info>中的</Address>。注意:属性处于不同的级别。

<Detail   DetailKey="11119612" DetailNo="123456" DetailType="A">
    <Infos>
        <Info InfoKey="11111599613" SRNo="1" Class="C">
            <NameID NameID="121212" />
        </Info>
        <Info InfoKey="11111599612" SRNo="2" Class="A" >
            <NameID NameID="121213" />
        </Info>     
    </Infos>
    <Addresss>
        <Address AddressKey="11111591234" SRNo="1" >
            <NameID NameID="121212" />
        </Address>
        <Address AddressKey="11111593243" SRNo="2" >
            <NameID NameID="121213" />
        </Address>      
    </Addresss>
</Detail>

我尝试过的。

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
   <xsl:output method="xml" indent="yes" />
   <xsl:template match="/">
      <Detail>
         <Infos>
            <xsl:for-each select="Detail/Addresss/Address">
               <Info>
                  <xsl:attribute name="AddressKey">
                     <xsl:value-of select="@AddressKey" />
                  </xsl:attribute>
                  <xsl:variable name="vSRNo" select="@SRNo" />
                  <xsl:variable name="vNameID" select="NameID/@NameID" />
                  <xsl:attribute name="Class">
                     <xsl:value-of select="../../Infos/Info[@SRNo=$vSRNo]/Name[@NameID=$vNameID]/../@Class" />
                  </xsl:attribute>
               </Info>
            </xsl:for-each>
         </Infos>
      </Detail>
   </xsl:template>
</xsl:stylesheet>

1 个答案:

答案 0 :(得分:2)

这里有三个错误:

  • 您的元素名为NameID,而不是Name(这在两个地方都是错误的)
  • @ClassNameID上的一个属性,因此您之前不需要../

修复后,它会按预期工作:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
  <xsl:output method="xml" indent="yes" />
  <xsl:template match="/">
    <Detail>
      <Infos>
        <xsl:for-each select="Detail/Addresss/Address">
          <Info>
            <xsl:attribute name="AddressKey">
              <xsl:value-of select="@AddressKey" />
            </xsl:attribute>
            <xsl:variable name="vSRNo" select="@SRNo" />
            <xsl:variable name="vNameID" select="NameID/@NameID" />
            <xsl:attribute name="Class">
              <xsl:value-of select="/*/Infos/Info[@SRNo = $vSRNo and 
                                                  NameID/@NameID = $vNameID]/@Class" />
            </xsl:attribute>
          </Info>
        </xsl:for-each>
      </Infos>
    </Detail>
  </xsl:template>
</xsl:stylesheet>

稍微整理一下:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
  <xsl:output method="xml" indent="yes" />
  <xsl:key name="kInfo" match="Info"
           use="concat(@SRNo, '+', NameID/@NameID)"/>

  <xsl:template match="/">
    <Detail>
      <Infos>
        <xsl:apply-templates select="Detail/Addresss/Address" />
      </Infos>
    </Detail>
  </xsl:template>

  <xsl:template match="Address">
    <Info AddressKey="{@AddressKey}" 
          Class="{key('kInfo', concat(@SRNo, '+', NameID/@NameID))/@Class}" />
  </xsl:template>
</xsl:stylesheet>