Reputation: 125
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
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:
The identity rule copies every matched node "as-is".
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