Reputation: 526
I have this xml code and I want to select the <e>
and <z>
values in the whole document and sort them without any duplicates:
<root>
<a>
<b>2.7</b>
<c>
<d>
<e>NZ 5222</e>
</d>
<d>
<e>NZ 5223</e>
</d>
<d>
<e>NZ 5224</e>
</d>
<d>
<e>NZ 5225</e>
</d>
</c>
</a>
<a>
<b>2.7</b>
<c>
<d>
<e>NZ 5222</e>
</d>
<d>
<e>NZ 611</e>
</d>
<d>
<e>NZ 54</e>
</d>
<d>
<e>NZ 522</e>
</d>
</c>
</a>
<a>
<x>
<y>
<z>NZ 5222</z>
</y>
<y>
<z>NZ 677</z>
</y>
</x>
</a>
</root>
And this XSL stylesheet:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match='/'>
<xsl:variable name="unique-list" select="//e[ancestor::a/b='2.7' and not(.=following::e)]" />
<xsl:variable name="unique-list2" select="//z[not(.=following::z)]" />
<xsl:for-each select="$unique-list">
<xsl:value-of select="." />
<br/>
</xsl:for-each>
<xsl:for-each select="$unique-list2">
<xsl:value-of select="." />
<br/>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
Output is:
NZ 5222
NZ 5223
NZ 5224
NZ 5225
NZ 5222
NZ 611
NZ 54
NZ 522
NZ 5222
NZ 677
Desired Output with sorting and without any duplicates:
NZ 54
NZ 522
NZ 611
NZ 677
NZ 5222
NZ 5223
NZ 5224
NZ 5225
Upvotes: 0
Views: 165
Reputation: 116957
I want to select the
<e>
and<z>
values in the whole document and sort them without any duplicates
I suggest you use the Muenchian grouping method to eliminate duplicates. This is much more efficient than your atttempted method - and sorting will also become fairly trivial (other than the problem of sorting only by the numerical part of the value):
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" omit-xml-declaration="yes" version="1.0" encoding="utf-8" indent="yes"/>
<xsl:key name="k" match="e | z" use="." />
<xsl:template match="/root">
<xsl:for-each select="(a/c/d/e | a/x/y/z)[count(. | key('k', .)[1]) = 1]">
<xsl:sort select="substring-after(., ' ')" data-type="number" order="ascending"/>
<xsl:value-of select="." />
<br/>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
I only want to list
<e>
item when the child<b>
of the ancestor<a>
is equal to 2.7
Then change:
<xsl:for-each select="(a/c/d/e | a/x/y/z )[count(. | key('k', .)[1]) = 1]">
to:
<xsl:for-each select="(a[b=2.7]/c/d/e | a/x/y/z )[count(. | key('k', .)[1]) = 1]">
Note that this means "when any child <b>
of the ancestor <a>
is equal to 2.7".
Upvotes: 1