2FaceMan
2FaceMan

Reputation: 483

XSLT 'value-of select' on multiple attribute check at different level

This is a simplifed Xml example for the problem I am facing.I have to set attribute Class value in output xml by matching on NameID & SRNo in <Info> and </Address> . Note: Attributes are at different level.

<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>

What I have tried.

<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>

Upvotes: 1

Views: 5416

Answers (1)

JLRishe
JLRishe

Reputation: 101662

There were three mistakes here:

  • You have elements named NameID, not Name (this was wrong in two places)
  • @Class is an attribute on NameID, so you don't need a ../ before it.

Once these are fixed, it works as expected:

<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>

With a bit of tidying:

<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>

Upvotes: 3

Related Questions