dinakar
dinakar

Reputation: 125

Comparing 2 node sets based on attributes

i'm new to xslt pls provide the xslt that compare two node based on the attribute values.

input.xml:

<comp>
<alink>
<link id="0003"/>
<link id="0001"/>
<link id="0002"/>
 </alink>
<bibsection>
<bib id="0001">2007</bib>
 <bib id="0002">2008</bib>
<bib id="0003">2009</bib>
 </bibsection>
 </comp>

my output should be,

output.xml:

<comp>
<alink>
 <link id="0003"/><year>2009</year>
 <link id="0001"/><year>2007</year>
 <link id="0002"/><year>2008</year>
  </alink>
 <bibsection>
<bib id="0001">2007</bib>
 <bib id="0002">2008</bib>
 <bib id="0003">2009</bib>
  </bibsection>
  </comp>

thanks in advance.

Upvotes: 3

Views: 231

Answers (1)

Dimitre Novatchev
Dimitre Novatchev

Reputation: 243479

A complete, efficient and short transformation, using keys:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:key name="kBibById" match="bib" use="@id"/>

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

 <xsl:template match="link">
  <xsl:call-template name="identity"/>
  <year><xsl:value-of select="key('kBibById', @id)"/></year>
 </xsl:template>
</xsl:stylesheet>

When this transformation is applied on the provided XML document:

<comp>
    <alink>
        <link id="0003"/>
        <link id="0001"/>
        <link id="0002"/>
    </alink>
    <bibsection>
        <bib id="0001">2007</bib>
        <bib id="0002">2008</bib>
        <bib id="0003">2009</bib>
    </bibsection>
</comp>

the wanted, correct result is produced:

<comp>
   <alink>
      <link id="0003"/>
      <year>2009</year>
      <link id="0001"/>
      <year>2007</year>
      <link id="0002"/>
      <year>2008</year>
   </alink>
   <bibsection>
      <bib id="0001">2007</bib>
      <bib id="0002">2008</bib>
      <bib id="0003">2009</bib>
   </bibsection>
</comp>

Explanation:

  1. The identity rule copies every matched node "as-is".

  2. There is a single template overriding the identity template -- and it matches any link element. The code in the body of this template calls the identity template by name to process the matched link element, then constructs a year element, with a text node child whose value is the string value of the first bib element whose id attribute has the same value as the id attribute of the matched link element. Selecting this bib element is done using the key() function that references an xsl:key instruction named "kBibById".

Notice:

The link to the identity rule above is temporarily inoperable -- for the time-being, please, use this one form the Internet Archives:

http://web.archive.org/web/20081229160200/http://www.dpawson.co.uk/xsl/sect2/identity.html

Upvotes: 1

Related Questions