用于对xml子节点排序的xsl
下面是示例xml用于对xml子节点排序的xsl,xml,xslt,sorting,Xml,Xslt,Sorting,下面是示例xml <Data version="2.0"> <Group> <Item>3</Item> <Item>1</Item> <Item>2</Item> </Group> <Group> <Item>7</Item> <Item>5&
<Data version="2.0">
<Group>
<Item>3</Item>
<Item>1</Item>
<Item>2</Item>
</Group>
<Group>
<Item>7</Item>
<Item>5</Item>
</Group>
</Data>
所以问题是:1。为什么分类不起作用。如何保留所有节点和xml的结构?这就是您想要的:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Group">
<xsl:copy>
<xsl:apply-templates select="@*"/>
<xsl:apply-templates select="Item">
<xsl:sort select="text()" />
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
第一个模板是“身份模板”(GoogleIT),它将输入复制到输出,不做任何更改。然后,对于组节点,我们将其复制到输出(
),复制其属性,然后在对嵌套项节点进行排序后复制它们。它们被复制是因为内部的
最终使用了标识模板,因为没有更具体的条目节点模板
注意,如果
Group
节点可以包含Item
节点之外的其他内容,那么您必须确保它也被复制。上面的模板将丢弃它们。@Jim的答案基本正确
但是,应用于稍微更真实的XML文档,例如:
<Data version="2.0">
<Group>
<Item>3</Item>
<Item>1</Item>
<Item>10</Item>
<Item>2</Item>
</Group>
<Group>
<Item>7</Item>
<Item>5</Item>
</Group>
</Data>
<Data version="2.0">
<Group>
<Item>1</Item>
<Item>2</Item>
<Item>3</Item>
<Item>10</Item>
</Group>
<Group>
<Item>5</Item>
<Item>7</Item>
</Group>
</Data>
3.
1.
10
2.
7.
5.
生成的结果显然不是您想要的结果(2和3之前是10):
1.
10
2.
3.
5.
7.
以下是正确的解决方案(也略短):
将此转换应用于同一XML文档(如上)时,将生成所需的正确结果:
<Data version="2.0">
<Group>
<Item>3</Item>
<Item>1</Item>
<Item>10</Item>
<Item>2</Item>
</Group>
<Group>
<Item>7</Item>
<Item>5</Item>
</Group>
</Data>
<Data version="2.0">
<Group>
<Item>1</Item>
<Item>2</Item>
<Item>3</Item>
<Item>10</Item>
</Group>
<Group>
<Item>5</Item>
<Item>7</Item>
</Group>
</Data>
1.
2.
3.
10
5.
7.
解释:使用的数据类型
属性指定排序键值应视为数字,而不是(默认)字符串
<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="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Group">
<Group>
<xsl:apply-templates select="*">
<xsl:sort data-type="number"/>
</xsl:apply-templates>
</Group>
</xsl:template>
</xsl:stylesheet>
<Data version="2.0">
<Group>
<Item>1</Item>
<Item>2</Item>
<Item>3</Item>
<Item>10</Item>
</Group>
<Group>
<Item>5</Item>
<Item>7</Item>
</Group>
</Data>