我的输入是一些未排序的 XML,我想对其进行排序 - 首先按字母顺序排序,因为我在尝试使用 XSL 对 XML 文件进行排序时遇到了问题。我想对任意数量的嵌套节点进行排序,首先按节点的字母顺序排序,然后根据需要按文本值的字母顺序排序。
我在“列出”项目的一致排序方面遇到问题。在下面的示例中,似乎“有时”它会根据标题对两本书进行排序,而其他时候它会根据作者进行排序。我认为这与 XML 在输入时的排序方式有关,但我不知道这是如何出现的。 我不在乎哪本书先出现,只关心它的一致性。另外,我希望它能够普遍工作。该列表可以是电影,也可以嵌套得更深。
输入示例:
<root>
<nodeA>text</nodeA>
<nodeC>text</nodeC>
<nodeB>text</nodeB>
<bookList>
<book>
<title>ABC</title>
<author>John</author>
</book>
<book>
<title>XYZ</title>
<author>Dan</author>
</book>
</bookList>
</root>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml"/>
<xsl:strip-space elements="*"/>
<xsl:template match="*">
<xsl:copy>
<xsl:apply-templates>
<xsl:sort select="name()"/>
<xsl:sort select="."/>
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
<root>
<bookList>
<book>
<author>John</author>
<title>ABC</title>
</book>
<book>
<author>Dan</author>
<title>XYZ</title>
</book>
</bookList>
<nodeA>text</nodeA>
<nodeB>text</nodeB>
<nodeC>text</nodeC>
</root>
<root>
<bookList>
<book>
<author>Dan</author>
<title>XYZ</title>
</book>
<book>
<author>John</author>
<title>ABC</title>
</book>
</bookList>
<nodeA>text</nodeA>
<nodeB>text</nodeB>
<nodeC>text</nodeC>
</root>
如上所述,我对任一输出都满意,但我需要它与任何输入顺序一致地工作。
您可以尝试一种管道方法,首先按元素名称对 xml 进行排序,然后按第一个元素的内容进行以下转换。
在 xslt 中你可以做这样的事情:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml"/>
<xsl:strip-space elements="*"/>
<xsl:output indent="yes"/>
<xsl:template match="/">
<xsl:variable name="step1">
<xsl:apply-templates mode="step1"/>
</xsl:variable>
<xsl:apply-templates select="$step1" mode="step2"/>
</xsl:template>
<xsl:template match="*" mode="step1">
<xsl:copy>
<xsl:apply-templates mode="step1">
<xsl:sort select="name()"/>
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
<xsl:template match="*" mode="step2">
<xsl:copy>
<xsl:apply-templates mode="step2">
<xsl:sort select="*[1]/text()"/>
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>