xml - XML 元素的自定义排序

标签 xml xslt xslt-1.0

给定以下形式的输入 XML:

<root>
    <alpha />
    <beta />
    <gamma />
</root>

我希望能够按照 XSL 样式表中定义的自定义顺序处理元素。我试过:

<xsl:stylesheet version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:my="http://tempurl.org" 
    exclude-result-prefixes="my">

    <xsl:output omit-xml-declaration="yes" indent="yes" />

    <!-- Elements should be processed in the following order: -->
    <my:sorting>
        <my:item id="beta" />
        <my:item id="gamma" />
        <my:item id="alpha" />
    </my:sorting>

    <xsl:template match="root">
        <xsl:variable name="sortOrder" select="document('')/*/my:sorting/my:item" />

        <xsl:apply-templates>
            <xsl:sort select="count($sortOrder[@id=name()]/preceding-sibling::*)"/>
        </xsl:apply-templates>
    </xsl:template>

    <xsl:template match="*">
        <xsl:value-of select="name()" />
    </xsl:template>
</xsl:stylesheet>

但这对排序没有影响。

这样的解决方案可能吗?我刚刚在 XSL 中犯了一些简单的错误吗?

(我知道涉及 string-lengthsubstring-before 的不同解决方案,但我想知道如何让事情以类似的方式工作如果可能的话,与上面的内容相同。)

最佳答案

问题出在 xsl:sort

<xsl:sort select="count($sortOrder[@id=name()]/preceding-sibling::*)"/>

在表达式中,name() 是上下文相关的。它是应用于节点集 (sortOrder) 的条件的一部分,因此将返回 sortOrder 元素的名称。本质上,它正在寻找名称等于其 id 属性的 sortOrder 元素。

要解决此问题,请使用 current() 函数

<xsl:sort select="count($sortOrder[@id=name(current())]/preceding-sibling::*)"/>

另一种方法,虽然不那么优雅,是将排序顺序定义为分隔字符串,如下所示:

<xsl:variable name="sortOrder" select="'|beta|alpha|gamma|'" />

然后你的排序表达式就变成这样了,主要是按元素名称在字符串中的位置进行排序。

 <xsl:sort select="string-length(substring-before($sortOrder, concat('|', name(), '|')))" data-type="number"/>

在本例中,name() 不是条件的一部分,因此上下文是您要排序的元素。

关于xml - XML 元素的自定义排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26026999/

相关文章:

XML 和 XSLT 将输出写入文本文件

xslt - 如何从匹配属性值的节点集中获取节点?

Java解析XML文档给出 “Content not allowed in prolog”错误

java - 在 Android 中重复写入 XML 文件的最有效方法是什么?

php - 使用 php 创建 rdf/xml 的简单方法?

javax Transformer 保留转义实体

xml - 使用 group-by 对元素进行分组

xml - 使用散列键通过 XML::LibXML 编写 xml 文件时出现编码错误

xslt - 获取当前节点 xpath

xml - XSLT 1.0 如何将 namespace 声明保留在根目录中