我无法实现排序。我有一个XML文档,除了按顺序排序某些元素外,我想做1副本。复制后文档的结构必须相同才能验证模式。我无法控制架构,所以我无法修改它。这是我的XML数据的简化版本:
<ResponseDoc xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<resHead>
<id>R1983Rs</id>
</resHead>
<item>
<objRef>
<objId>100</objId>
<sysId>xyz</sysId>
</objRef>
<!-- Additional data here -->
</item>
<item>
<objRef>
<objId>140</objId>
<sysId>abc</sysId>
</objRef>
<!-- Additional data here -->
</item>
<resFoot>
<id>1234</id>
</resFoot>
</ResponseDoc>
我想将<item>
元素排序为特定的顺序。生成的XML文件应为:
<ResponseDoc xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<resHead>
<id>R1983Rs</id>
</resHead>
<item>
<objRef>
<objId>140</objId>
<sysId>abc</sysId>
</objRef>
<!-- Additional data here -->
</item>
<item>
<objRef>
<objId>100</objId>
<sysId>xyz</sysId>
</objRef>
<!-- Additional data here -->
</item>
<resFoot>
<id>1234</id>
</resFoot>
</ResponseDoc>
我成功地使用以下XSL样式表进行排序:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<xsl:output method="xml" omit-xml-declaration="yes" indent="yes" />
<xsl:template match="ResponseDoc">
<xsl:copy>
<xsl:apply-templates select="resHead" />
<xsl:apply-templates select="item">
<xsl:sort select="number(objRef/objId)" order="descending" />
</xsl:apply-templates>
<xsl:apply-templates select="resFoot" />
</xsl:copy>
</xsl:template>
<xsl:template match="node() | @*">
<xsl:copy>
<xsl:apply-templates select="node() | @*" />
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
但这并不令人满意,因为我需要明确处理<resHead>
和<resFoot>
,如果架构扩展到包含<item>
的其他兄弟,我需要搜索出来这个XSL并修改它。我做了大量的研究,但只找到不包含任何兄弟元素或在某些“容器”元素中包含“已排序”元素的例子,即:
...
<items>
<item>...</item>
<item>...</item>
<item>...</item>
</items>
...
我想找到更通用的方法来完成排序。我尝试了很多工作样式表的变量,但我丢失或重新定位兄弟节点或打破排序。任何人都可以帮忙吗?
答案 0 :(得分:0)
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<xsl:output method="xml" omit-xml-declaration="yes" indent="yes" />
<xsl:template match="/">
<xsl:for-each select="ResponseDoc">
<xsl:sort select="item" order="descending" />
<xsl:copy-of select="." />
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
答案 1 :(得分:0)
如果所有item
元素都是连续的,这是一个有效的解决方案:
<xsl:template match="ResponseDoc">
<xsl:copy>
<xsl:apply-templates select="item[1]/preceding-sibling::*" />
<xsl:apply-templates select="item">
<xsl:sort select="number(objRef/objId)" order="descending" />
</xsl:apply-templates>
<xsl:apply-templates select="item[last()]/following-sibling::*" />
</xsl:copy>
</xsl:template>
它只是在第一个item
元素之前而不是resHead
之前的任何兄弟姐妹,以及在最后一个item
元素之后而不是resFoot
之后的任何兄弟之类。< / p>