如何在XSLT 2.0中基于<three>键重新排序含子节点的<node>节点
Reordering Elements by Value in XSLT
To achieve your goal of moving all <node> elements with value=2 to the front (before the first non-value-2 <node>), while keeping the <three> element intact, you can use a combination of the identity template (to preserve most content) and a custom template to reorder the target nodes.
Step 1: Sample Input XML
Let’s use a concrete example of your input structure to demonstrate:
<root> <three>sample-key</three> <node> <value>1</value> <content>Node 1 content</content> </node> <node> <value>3</value> <content>Node 3 content</content> </node> <node> <value>2</value> <content>Node 2 content</content> </node> <node> <value>2</value> <content>Another Node 2 content</content> </node> </root>
Step 2: XSLT Solution
Here’s the code that will reorder the nodes as requested:
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <!-- Identity template: copies all content by default --> <xsl:template match="@* | node()"> <xsl:copy> <xsl:apply-templates select="@* | node()"/> </xsl:copy> </xsl:template> <!-- Custom template for the parent element holding <three> and <node> --> <xsl:template match="*[three and node]"> <xsl:copy> <!-- Keep <three> in its original position --> <xsl:apply-templates select="three"/> <!-- First, output all <node> elements with value=2 --> <xsl:apply-templates select="node[value=2]"/> <!-- Then, output all remaining <node> elements (value != 2) --> <xsl:apply-templates select="node[value != 2]"/> <!-- Copy any other child elements besides <three> and <node> --> <xsl:apply-templates select="*[not(self::three or self::node)]"/> </xsl:copy> </xsl:template> </xsl:stylesheet>
Step 3: Breakdown of the Solution
- Identity Template: This is the backbone of most XSLT transformations—it copies every element, attribute, and text node exactly as-is, unless another template overrides it.
- Custom Parent Template: This targets any element that contains both
<three>and<node>children (replace*[three and node]with your parent element’s actual name, likematch="root", for more precision). Inside this template:- We first copy the
<three>element to preserve its original position. - We select and output all
<node>elements withvalue=2first. - Next, we output all remaining
<node>elements (wherevalue != 2) in their original relative order. - Finally, we copy any other child elements that aren’t
<three>or<node>to ensure nothing is lost.
- We first copy the
Step 4: Sample Output
Applying the XSLT to the sample input will produce this reordered output:
<root> <three>sample-key</three> <node> <value>2</value> <content>Node 2 content</content> </node> <node> <value>2</value> <content>Another Node 2 content</content> </node> <node> <value>1</value> <content>Node 1 content</content> </node> <node> <value>3</value> <content>Node 3 content</content> </node> </root>
Quick Notes
- If your
<node>elements might have multiple<value>children, adjust the test tovalue[1]=2to target the first<value>element inside each<node>. - If your parent element has a specific name (e.g.,
<container>), replace the generic match pattern with that name for a more precise transformation.
内容的提问来源于stack exchange,提问作者Sojimanatsu
相关产品推荐
相关产品推荐

