【问题标题】:XPath 1.0 Order of returned attributes in a UNIONXPath 1.0 UNION 中返回属性的顺序
【发布时间】:2014-03-28 01:23:19
【问题描述】:
<merge>
    <text>
        <div begin="A"   end="B" />
        <div begin="C"   end="D" />
        <div begin="E"   end="F" />
        <div begin="G"   end="H" />
    </text>
</merge>

我需要一组 UNIONed 属性节点,按 A、B、C、D、E、F、G、H 的顺序排列,这样就可以了:

/merge/text/div/@begin | /merge/text/div/@end

但前提是每个@begin 都在每个@end 之前,因为UNION 运算符被指定为按文档顺序返回节点。 (是吗?)

我需要节点集的顺序相同,即使属性在文档中以不同的顺序出现,如下所示:

<merge>
    <text>
        <div end="B"   begin="A" />
        <div begin="C" end="D"   />
        <div end="F"   begin="E" />
        <div begin="G" end="H"   />
    </text>
</merge>

也就是说,我需要元素遵循文档顺序,但每个元素中的属性都遵循确定的顺序(指定的或按属性名称的字母顺序)。

【问题讨论】:

    标签: xpath


    【解决方案1】:

    这在纯 XPath 中根本不可能。首先,XML 中的属性是无序的。来自XML 1.0 Recommendation

    请注意,开始标签中属性规范的顺序或 空元素标签不重要。

    XPath 引擎可能会按照它们在文档中出现的顺序读取和存储它们,但就规范而言,这只是一个不可信赖的巧合。

    其次,XPath 没有排序功能。因此,您最好的选择是在选定元素后以您的宿主语言(例如 XSLT 或通用 PL)对元素进行排序。

    下面是如何在 XSLT 中按值对这些属性进行排序:

    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
        <xsl:output method="text"/>
        <xsl:template match="/">
            <xsl:apply-templates
                select="/merge/text/div/@*[name()='begin' or name()='end']">
                <xsl:sort select="."/>
            </xsl:apply-templates>
        </xsl:template>
    </xsl:stylesheet>
    

    请注意,我还将您的两个表达式合并为一个。

    编辑:使用以下命令按文档顺序输出开始/结束对(如 cmets 中所述):

    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
        <xsl:output method="text"/>
        <xsl:strip-space elements="*"/>
        <xsl:template match="div">
            <xsl:value-of select="concat(@begin, @end)"/>
        </xsl:template>
    </xsl:stylesheet>
    

    【讨论】:

    • 不是我想要的答案,但仍然是答案。我会把这个问题交给 XSLT jockeys。
    • @JPM - 我可以在这里发布一个 XSLT 解决方案。一分钟。
    • 那会按属性值排序,对吧?我需要 begin-end-begin-end-... 顺序,即使值会以其他方式排序。 (我不应该在我的例子中使用 ABCDEFGH。)
    • 结果还没有输出。我需要可以在 with-param 选择表达式中传递的节点集。如果我可以传递一个开始-结束对的节点集,那可能会起作用。
    • @JPM- 好的,我建议将其作为一个单独的问题发布在 XSLT 标记中,这样我们就不会在这里反复讨论。发布这些确切的要求,我相信你会得到一个很好的答案。
    猜你喜欢
    • 2014-11-16
    • 2012-11-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-25
    • 1970-01-01
    • 2023-03-06
    • 1970-01-01
    相关资源
    最近更新 更多