Reputation: 601
I have been trying to change the order of the nodes based on structure.
Lets assume that we have an example xml
<?xml version="1.0" encoding="UTF-8"?>
<ParentNode>
<example>value</example>
<example>value</example>
<node>
<one>1</one>
<two>1</two>
<three>1</three>
<four>1</four>
</node>
<node>
<one>2</one>
<two>2</two>
<three>2</three>
<four>2</four>
</node>
</ParentNode>
This <node>
part is repeating for other values as well, this is the simplified version of the whole structure.
What i want is: I want to change the order of the <node>
with values 2 , with <node>
with values 1
<?xml version="1.0" encoding="UTF-8"?>
<ParentNode>
<example>value</example>
<example>value</example>
<node>
<one>2</one>
<two>2</two>
<three>2</three>
<four>2</four>
</node>
<node>
<one>1</one>
<two>1</two>
<three>1</three>
<four>1</four>
</node>
</ParentNode>
Lets assume that, <three>
is a key value for us to re-order the nodes, So i would like to say <xsl:when test="value=2">
put whole before the first one.
How can i write it in XSLT 2.0 ?
EDIT: I found the solution by changing the variables inside the templates, So What i did is, putting the value "2" nodes into "1" and, This is a manual solution, but at the end, it works. Thank you for the ideas
Upvotes: 0
Views: 259
Reputation: 167516
Write two templates
<xsl:template match="node[three = 1]">
<xsl:copy-of select="../node[three = 2]"/>
</xsl:template>
<xsl:template match="node[three = 2]">
<xsl:copy-of select="../node[three = 1]"/>
</xsl:template>
plus the identity transformation and the two elements are swapped (XSLT 3 version at http://xsltfiddle.liberty-development.net/3Nqn5Yd, for XSLT 2 you have to spell out the identity transformation template:
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="node[three = 1]">
<xsl:copy-of select="../node[three = 2]"/>
</xsl:template>
<xsl:template match="node[three = 2]">
<xsl:copy-of select="../node[three = 1]"/>
</xsl:template>
</xsl:transform>
http://xsltransform.hikmatu.com/gWcDMek
Upvotes: 2
Reputation: 29022
If you happen to have any literal order in your node
s values you could use the xsl:sort
function to reorder your them:
<xsl:template match="/ParentNode">
<xsl:copy>
<xsl:copy-of select="example" />
<xsl:for-each select="node">
<xsl:sort select="three" order="descending" />
<xsl:copy>
<xsl:copy-of select="node()|@*" />
</xsl:copy>
</xsl:for-each>
</xsl:copy>
</xsl:template>
Output:
<ParentNode>
<example>value</example>
<example>value</example>
<node>
<one>2</one>
<two>2</two>
<three>2</three>
<four>2</four>
</node>
<node>
<one>1</one>
<two>1</two>
<three>1</three>
<four>1</four>
</node>
</ParentNode>
Upvotes: 1