我想按字母顺序按同一级别的元素对xml文件进行排序。这意味着,在第一级对元素进行排序,然后在每个元素内对它们的子元素进行递归,依此类推。它必须是多级的,而不仅仅是一个级别(在其他问题中解决)。例如(请忽略内容和含义):
<example>
<note>
<to>Tove</to>
<from>Jani</from>
<heading>Reminder</heading>
<headb>head</head3>
<heada>head</head3>
<body>Don't forget me this weekend!</body>
</note>
<next>
<c>blabla</c>
<a>blabla</a>
</next>
</example>
要:
<example>
<next>
<a>blabla</a>
<c>blabla</c>
</next>
<note>
<body>Don't forget me this weekend!</body>
<from>Jani</from>
<heading>Reminder</heading>
<heada>head</head3>
<headb>head</head3>
<to>Tove</to>
</note>
</example>
xml可以包含数千行和多个元素级别
答案 0 :(得分:1)
您应该能够使用身份转换并添加xsl:sort
以对name()
或local-name()
进行排序。
示例...
XML输入(格式良好,比原版稍微复杂一点。)
<example>
<note>
<to>Tove</to>
<from>Jani</from>
<heading>Reminder</heading>
<headb>head</headb>
<heada>head</heada>
<body>Don't forget me this weekend!</body>
</note>
<next>
<c>blabla</c>
<a>blabla</a>
</next>
<djh>
<!-- comment -->
<foo attr="test">
<bar>
<baz>text</baz>
<foo><!--comment--></foo>
</bar>
<baz attr="test">
<foo/>
<bar/>
</baz>
</foo>
<?PI?>
<baz>
<bar>
<foo/>
<baz/>
</bar>
<foo>
<bar/>
<baz/>
</foo>
</baz>
</djh>
</example>
XSLT 1.0
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()">
<xsl:sort select="local-name()"/>
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
XML输出
<example>
<djh><!-- comment --><?PI?>
<baz>
<bar>
<baz/>
<foo/>
</bar>
<foo>
<bar/>
<baz/>
</foo>
</baz>
<foo attr="test">
<bar>
<baz>text</baz>
<foo><!--comment--></foo>
</bar>
<baz attr="test">
<bar/>
<foo/>
</baz>
</foo>
</djh>
<next>
<a>blabla</a>
<c>blabla</c>
</next>
<note>
<body>Don't forget me this weekend!</body>
<from>Jani</from>
<heada>head</heada>
<headb>head</headb>
<heading>Reminder</heading>
<to>Tove</to>
</note>
</example>
请注意,评论和处理说明最终会浮动到排序顺序的顶部。
另请注意,如果您有混合内容(同一父级中的元素和文本节点),您可能希望跳过该元素的排序。否则,文本将在排序顺序中排在第一位(如注释和处理说明)。
这是一种跳过混合内容元素的方法(注释和处理指令输出确实发生了变化,因此您可能需要进行实验):
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="*[not(text())]">
<xsl:copy>
<xsl:apply-templates select="@*|node()">
<xsl:sort select="local-name()"/>
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>