Xml 混合子级的XSLT排序
我有以下XML:Xml 混合子级的XSLT排序,xml,sorting,xslt,Xml,Sorting,Xslt,我有以下XML: <root> <nodeLevel1> <nodeType1>node type 1</nodeType1> <nodeType2><rank>3</rank></nodeType2> <nodeType2><rank>1</rank></nodeType2> <nodeType2><
<root>
<nodeLevel1>
<nodeType1>node type 1</nodeType1>
<nodeType2><rank>3</rank></nodeType2>
<nodeType2><rank>1</rank></nodeType2>
<nodeType2><rank>4</rank></nodeType2>
<nodeType2><rank>2</rank></nodeType2>
<nodeType3>node type 3</nodeType3>
</nodeLevel1>
</root>
节点类型1
3.
1.
4.
2.
节点类型3
我使用以下XSLT对该XML进行排序:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" omit-xml-declaration="no" indent="yes" media-type="text/html"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="nodeLevel1">
<xsl:copy>
<xsl:apply-templates select="node()|@*">
<xsl:sort select="rank" data-type="number" />
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
结果是:
<?xml version="1.0" encoding="UTF-8"?>
<root>
<nodeLevel1>
<nodeType1>node type 1</nodeType1>
<nodeType3>node type 3</nodeType3>
<nodeType2>
<rank>1</rank>
</nodeType2>
<nodeType2>
<rank>2</rank>
</nodeType2>
<nodeType2>
<rank>3</rank>
</nodeType2>
<nodeType2>
<rank>4</rank>
</nodeType2>
</nodeLevel1>
</root>
节点类型1
节点类型3
1.
2.
3.
4.
问题是所有的“nodeType2”在我的XML中都不在正确的位置。
如何将节点“nodeType1”保留在“nodeType2”之前,将节点“nodeType3”保留在“nodeType2”之后。(解决方案不得使用元素名称“nodeType1”或“nodeType3”,因为它可以重命名为任何名称)
因此,结果应该是:
<?xml version="1.0" encoding="UTF-8"?>
<root>
<nodeLevel1>
<nodeType1>node type 1</nodeType1>
<nodeType2>
<rank>1</rank>
</nodeType2>
<nodeType2>
<rank>2</rank>
</nodeType2>
<nodeType2>
<rank>3</rank>
</nodeType2>
<nodeType2>
<rank>4</rank>
</nodeType2>
<nodeType3>node type 3</nodeType3>
</nodeLevel1>
</root>
节点类型1
1.
2.
3.
4.
节点类型3
感谢您的帮助。一种方法是使用与第一个节点pe2元素匹配的模板
<xsl:template match="nodeType2[1]">
在这里,您可以选择并排序所有nodeType2元素
<xsl:for-each select="self::*|following-sibling::nodeType2">
<xsl:sort select="rank" data-type="number" />
<!-- Copy element -->
<xsl:call-template name="identity" />
</xsl:for-each>
您唯一需要的另一件事是另一个模板,以阻止另一个节点pe2元素被输出两次
<xsl:template match="nodeType2" />
这是完整的XSLT
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" omit-xml-declaration="no" indent="yes" media-type="text/html"/>
<xsl:template match="node()|@*" name="identity">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="nodeType2[1]">
<xsl:for-each select="self::*|following-sibling::nodeType2">
<xsl:sort select="rank" data-type="number" />
<xsl:call-template name="identity" />
</xsl:for-each>
</xsl:template>
<xsl:template match="nodeType2" />
</xsl:stylesheet>
应用于XML时,将输出以下内容
<root>
<nodeLevel1>
<nodeType1>node type 1</nodeType1>
<nodeType2>
<rank>1</rank>
</nodeType2>
<nodeType2>
<rank>2</rank>
</nodeType2>
<nodeType2>
<rank>3</rank>
</nodeType2>
<nodeType2>
<rank>4</rank>
</nodeType2>
<nodeType3>node type 3</nodeType3>
</nodeLevel1>
</root>
节点类型1
1.
2.
3.
4.
节点类型3
此转换适用于任何元素名称(没有名称是硬编码的),并且非常有效,因为它使用键来标识组:
<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="kSameNamed" match="nodeLevel1/*" use=
"generate-id(preceding-sibling::*[not(name()=name(current()))][1])"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="nodeLevel1">
<nodeLevel1>
<xsl:apply-templates select=
"*[not(name() = name(preceding-sibling::*[1]))]"/>
</nodeLevel1>
</xsl:template>
<xsl:template match="nodeLevel1/*">
<xsl:for-each select="key('kSameNamed', generate-id(preceding-sibling::*[1]))">
<xsl:sort select="rank" data-type="number"/>
<xsl:copy-of select="."/>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
应用于提供的XML文档时:
<root>
<nodeLevel1>
<nodeType1>node type 1</nodeType1>
<nodeType2><rank>3</rank></nodeType2>
<nodeType2><rank>1</rank></nodeType2>
<nodeType2><rank>4</rank></nodeType2>
<nodeType2><rank>2</rank></nodeType2>
<nodeType3>node type 3</nodeType3>
</nodeLevel1>
</root>
<root>
<nodeLevel1>
<nodeType1>node type 1</nodeType1>
<nodeType2>
<rank>1</rank>
</nodeType2>
<nodeType2>
<rank>2</rank>
</nodeType2>
<nodeType2>
<rank>3</rank>
</nodeType2>
<nodeType2>
<rank>4</rank>
</nodeType2>
<nodeType3>node type 3</nodeType3>
</nodeLevel1>
</root>
<r>
<nodeLevel1>
<X1>node type 1</X1>
<Y2><rank>3</rank></Y2>
<Y2><rank>1</rank></Y2>
<Y2><rank>4</rank></Y2>
<Y2><rank>2</rank></Y2>
<Z3>node type 3</Z3>
<A4><rank>8</rank></A4>
<A4><rank>2</rank></A4>
<A4><rank>9</rank></A4>
<A4><rank>3</rank></A4>
<B5><rank>8</rank></B5>
<B5><rank>2</rank></B5>
<B5><rank>9</rank></B5>
<B5><rank>3</rank></B5>
<C7>Node of Type C7</C7>
</nodeLevel1>
</r>
<r>
<nodeLevel1>
<X1>node type 1</X1>
<Y2>
<rank>1</rank>
</Y2>
<Y2>
<rank>2</rank>
</Y2>
<Y2>
<rank>3</rank>
</Y2>
<Y2>
<rank>4</rank>
</Y2>
<Z3>node type 3</Z3>
<A4>
<rank>2</rank>
</A4>
<A4>
<rank>3</rank>
</A4>
<A4>
<rank>8</rank>
</A4>
<A4>
<rank>9</rank>
</A4>
<B5>
<rank>2</rank>
</B5>
<B5>
<rank>3</rank>
</B5>
<B5>
<rank>8</rank>
</B5>
<B5>
<rank>9</rank>
</B5>
<C7>Node of Type C7</C7>
</nodeLevel1>
</r>
节点类型1
3.
1.
4.
2.
节点类型3
生成所需的正确结果:
<root>
<nodeLevel1>
<nodeType1>node type 1</nodeType1>
<nodeType2><rank>3</rank></nodeType2>
<nodeType2><rank>1</rank></nodeType2>
<nodeType2><rank>4</rank></nodeType2>
<nodeType2><rank>2</rank></nodeType2>
<nodeType3>node type 3</nodeType3>
</nodeLevel1>
</root>
<root>
<nodeLevel1>
<nodeType1>node type 1</nodeType1>
<nodeType2>
<rank>1</rank>
</nodeType2>
<nodeType2>
<rank>2</rank>
</nodeType2>
<nodeType2>
<rank>3</rank>
</nodeType2>
<nodeType2>
<rank>4</rank>
</nodeType2>
<nodeType3>node type 3</nodeType3>
</nodeLevel1>
</root>
<r>
<nodeLevel1>
<X1>node type 1</X1>
<Y2><rank>3</rank></Y2>
<Y2><rank>1</rank></Y2>
<Y2><rank>4</rank></Y2>
<Y2><rank>2</rank></Y2>
<Z3>node type 3</Z3>
<A4><rank>8</rank></A4>
<A4><rank>2</rank></A4>
<A4><rank>9</rank></A4>
<A4><rank>3</rank></A4>
<B5><rank>8</rank></B5>
<B5><rank>2</rank></B5>
<B5><rank>9</rank></B5>
<B5><rank>3</rank></B5>
<C7>Node of Type C7</C7>
</nodeLevel1>
</r>
<r>
<nodeLevel1>
<X1>node type 1</X1>
<Y2>
<rank>1</rank>
</Y2>
<Y2>
<rank>2</rank>
</Y2>
<Y2>
<rank>3</rank>
</Y2>
<Y2>
<rank>4</rank>
</Y2>
<Z3>node type 3</Z3>
<A4>
<rank>2</rank>
</A4>
<A4>
<rank>3</rank>
</A4>
<A4>
<rank>8</rank>
</A4>
<A4>
<rank>9</rank>
</A4>
<B5>
<rank>2</rank>
</B5>
<B5>
<rank>3</rank>
</B5>
<B5>
<rank>8</rank>
</B5>
<B5>
<rank>9</rank>
</B5>
<C7>Node of Type C7</C7>
</nodeLevel1>
</r>
节点类型1
1.
2.
3.
4.
节点类型3
如果我们现在对完全不同的XML文档应用相同的转换:
<root>
<nodeLevel1>
<nodeType1>node type 1</nodeType1>
<nodeType2><rank>3</rank></nodeType2>
<nodeType2><rank>1</rank></nodeType2>
<nodeType2><rank>4</rank></nodeType2>
<nodeType2><rank>2</rank></nodeType2>
<nodeType3>node type 3</nodeType3>
</nodeLevel1>
</root>
<root>
<nodeLevel1>
<nodeType1>node type 1</nodeType1>
<nodeType2>
<rank>1</rank>
</nodeType2>
<nodeType2>
<rank>2</rank>
</nodeType2>
<nodeType2>
<rank>3</rank>
</nodeType2>
<nodeType2>
<rank>4</rank>
</nodeType2>
<nodeType3>node type 3</nodeType3>
</nodeLevel1>
</root>
<r>
<nodeLevel1>
<X1>node type 1</X1>
<Y2><rank>3</rank></Y2>
<Y2><rank>1</rank></Y2>
<Y2><rank>4</rank></Y2>
<Y2><rank>2</rank></Y2>
<Z3>node type 3</Z3>
<A4><rank>8</rank></A4>
<A4><rank>2</rank></A4>
<A4><rank>9</rank></A4>
<A4><rank>3</rank></A4>
<B5><rank>8</rank></B5>
<B5><rank>2</rank></B5>
<B5><rank>9</rank></B5>
<B5><rank>3</rank></B5>
<C7>Node of Type C7</C7>
</nodeLevel1>
</r>
<r>
<nodeLevel1>
<X1>node type 1</X1>
<Y2>
<rank>1</rank>
</Y2>
<Y2>
<rank>2</rank>
</Y2>
<Y2>
<rank>3</rank>
</Y2>
<Y2>
<rank>4</rank>
</Y2>
<Z3>node type 3</Z3>
<A4>
<rank>2</rank>
</A4>
<A4>
<rank>3</rank>
</A4>
<A4>
<rank>8</rank>
</A4>
<A4>
<rank>9</rank>
</A4>
<B5>
<rank>2</rank>
</B5>
<B5>
<rank>3</rank>
</B5>
<B5>
<rank>8</rank>
</B5>
<B5>
<rank>9</rank>
</B5>
<C7>Node of Type C7</C7>
</nodeLevel1>
</r>
节点类型1
3.
1.
4.
2.
节点类型3
8.
2.
9
3.
8.
2.
9
3.
C7型节点
我们再次得到正确的结果:
<root>
<nodeLevel1>
<nodeType1>node type 1</nodeType1>
<nodeType2><rank>3</rank></nodeType2>
<nodeType2><rank>1</rank></nodeType2>
<nodeType2><rank>4</rank></nodeType2>
<nodeType2><rank>2</rank></nodeType2>
<nodeType3>node type 3</nodeType3>
</nodeLevel1>
</root>
<root>
<nodeLevel1>
<nodeType1>node type 1</nodeType1>
<nodeType2>
<rank>1</rank>
</nodeType2>
<nodeType2>
<rank>2</rank>
</nodeType2>
<nodeType2>
<rank>3</rank>
</nodeType2>
<nodeType2>
<rank>4</rank>
</nodeType2>
<nodeType3>node type 3</nodeType3>
</nodeLevel1>
</root>
<r>
<nodeLevel1>
<X1>node type 1</X1>
<Y2><rank>3</rank></Y2>
<Y2><rank>1</rank></Y2>
<Y2><rank>4</rank></Y2>
<Y2><rank>2</rank></Y2>
<Z3>node type 3</Z3>
<A4><rank>8</rank></A4>
<A4><rank>2</rank></A4>
<A4><rank>9</rank></A4>
<A4><rank>3</rank></A4>
<B5><rank>8</rank></B5>
<B5><rank>2</rank></B5>
<B5><rank>9</rank></B5>
<B5><rank>3</rank></B5>
<C7>Node of Type C7</C7>
</nodeLevel1>
</r>
<r>
<nodeLevel1>
<X1>node type 1</X1>
<Y2>
<rank>1</rank>
</Y2>
<Y2>
<rank>2</rank>
</Y2>
<Y2>
<rank>3</rank>
</Y2>
<Y2>
<rank>4</rank>
</Y2>
<Z3>node type 3</Z3>
<A4>
<rank>2</rank>
</A4>
<A4>
<rank>3</rank>
</A4>
<A4>
<rank>8</rank>
</A4>
<A4>
<rank>9</rank>
</A4>
<B5>
<rank>2</rank>
</B5>
<B5>
<rank>3</rank>
</B5>
<B5>
<rank>8</rank>
</B5>
<B5>
<rank>9</rank>
</B5>
<C7>Node of Type C7</C7>
</nodeLevel1>
</r>
节点类型1
1.
2.
3.
4.
节点类型3
2.
3.
8.
9
2.
3.
8.
9
C7型节点