Reputation: 23
I'm trying to do a sort on the following data.
<contents>
<content>
<id>
<text>
</content>
<relatedcontent>
<id>
<text>
</relatedcontent>
</contents>
This is just sample data simplified, but you get the idea. Its two different named nodes that contains the same structure.
Right now I have created two different templates to treat the content and relatedcontent separetly, but then sorting is also done separetly. Is there an easy way to sort both content and relatedcontent on ids? Lets say the <text>
contains a text. How could I then list all the <text>
-elements of content and relatedcontent sorted by id?
Thanks!
Upvotes: 2
Views: 572
Reputation: 243459
This transformation shows how this can be done:
<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:template match="/*">
<contents>
<xsl:apply-templates>
<xsl:sort select="id" data-type="number"/>
</xsl:apply-templates>
</contents>
</xsl:template>
<xsl:template match="content">
Content Here
</xsl:template>
<xsl:template match="relatedcontent">
Relatedcontent Here
</xsl:template>
</xsl:stylesheet>
when applied on the provided XML document (corrected to be well-formed):
<contents>
<content>
<id>3</id>
<text/>
</content>
<relatedcontent>
<id>2</id>
<text/>
</relatedcontent>
</contents>
the wanted, correctly sorted result is produced:
<contents>
Relatedcontent Here
Content Here
</contents>
Do note:
No use of <xsl:for-each>
. Only <xsl:apply-templates>
is used.
No use of the XPath union operator (yes, it is called the union operator, nothing to do with pipes).
If in the future a third element to be sorted on id
is added to the XML document, this transformation will still work without any changes.
Upvotes: 7
Reputation: 220752
Try something like this
<xsl:foreach select="//content | //relatedcontent">
<xsl:sort select="id" />
<xsl:value-of select="text" />
</xsl:foreach>
I guess the solution lies in the fact that you "join" //content
and //relatedcontent
into a single node-set using the union operator |
Upvotes: 8