XSLT如何仅对XML文档的字符串节点中的数值进行排序

Posted

技术标签:

【中文标题】XSLT如何仅对XML文档的字符串节点中的数值进行排序【英文标题】:XSLT how sort only numeric values within a string node of XML document 【发布时间】:2021-07-14 22:55:38 【问题描述】:

我有一个应用程序,它在节点中生成一个带有 css 格式的 xml 文档来装饰值。我以编程方式构建 XSLT 文档并将其应用于 xml,并且只想按数字对其进行排序。我正在用 javascript 处理 xml 和 xslt 文档,然后将结果显示为报告。节点值如下所示:

<span class="g">96%</span>
<span class="r">56.5%</span>

如何对值进行排序并忽略周围的任何文本?

编辑:翻译听起来像是可行的,但我不知道如何应用它。我有 n 个可点击的标题。单击时,文档会被修改并添加一个新的

<th id="hdr6" <a href="#" onClick="sortXML(6,&quot;Collections_502&quot;,false)">Collections 502</a></th>
... later in the doc...
<xsl:for-each select="records/record">
<xsl:sort select="Collections_502/@value" order="ascending"/>

所以,我不确定将翻译放在哪里。它看起来像:

<xsl:sort select="translate('Collections_502/@value','0123456789','')" order="ascending"/>

编辑 2: 有多个列可以单击进行排序。所以,xml 看起来像:

<records>
<record id="12">
<person_first value="Bob"/>
<person_int value="15844"/>
<Collections_502 value="<span class='a'>100%</span>"/>
<Data_Security_494 value="<span class='a'>100%</span>"/>
<EBO_505 value="0"/>
<FDCPA_499 value="<span class='c'>50%</span>"/>
<General_Compliance_498 value="<span class='a'>100%</span>"/>
<HIPAA_500 value="<span class='a'>100%</span>"/>
<History_and_Ethics_497 value="<span class='a'>100%</span>"/>
<Human_Resources_495 value="<span class='b'>67%</span>"/>
<TCPA_404 value="<span class='b'>67%</span>"/>
</record>
<record id="13">
<person_first value="Erik"/>
<person_int value="14238"/>
<Collections_502 value="0"/>
<Data_Security_494 value="<span class='a'>100%</span>"/>
<EBO_505 value="0"/>
<FDCPA_499 value="<span class='a'>91%</span>"/>
<General_Compliance_498 value="<span class='a'>100%</span>"/>
<HIPAA_500 value="<span class='a'>100%</span>"/>
<History_and_Ethics_497 value="<span class='a'>100%</span>"/>
<Human_Resources_495 value="<span class='a'>100%</span>"/>
<TCPA_404 value="<span class='a'>100%</span>"/>
</record>
</records>

我从网络上的一个示例中得到以下内容,“内部 translate() 删除所有感兴趣的字符(例如,数字)以获取外部 translate() 的字符串,它将这些非数字字符从原始字符串。”

<xsl:for-each select="records/record">
<xsl:sort select="translate('HIPAA_500/@value', translate('HIPAA_500/@value', '0123456789', ''), '')" data-type="number" order="ascending"/>

它不起作用。没有错误,只是没有排序。

【问题讨论】:

您可以使用translate() 函数删除%(或任何其他)字符。 翻译听起来可能有用。我已经更详细地编辑了帖子。对吗? 【参考方案1】:

在您的示例中,排序指令可能如下所示:

<xsl:for-each select="span">
    <xsl:sort select="translate(., '%', '')" data-type="number" order="ascending"/>
    <!-- do something -->
</xsl:for-each>

演示:https://xsltfiddle.liberty-development.net/pNEj9cR

【讨论】:

对不起,我知道的不够多,无法写出一个好问题。你的答案看起来不错,但我没有给你足够的信息。我在示例中添加了更多内容,以便您可以查看 xml。我真的不明白你的。在您的示例中,或者为什么仅删除了 % 。我发现的示例感觉不太对,但显然我不确定它的去向。 您添加的“XML”不是格式良好的 XML 文档,根本无法由 XSLT 处理。属性值中不能有未转义的 &lt;。如果没有这个,指令&lt;xsl:sort select="translate(HIPAA_500/@value, translate(HIPAA_500/@value, '0123456789', ''), '')" data-type="number" order="ascending"/&gt; 应该可以工作——假设属性包含一个正整数。请注意路径周围没有引号。 嗯...也许翻译不能与 哇!我只是把引号从路径上去掉了,它工作得很好。

以上是关于XSLT如何仅对XML文档的字符串节点中的数值进行排序的主要内容,如果未能解决你的问题,请参考以下文章

XML & .NET - 仅对最深节点中的元素进行排序

在XSLT中输出内容带有CDATA的XML节点

如何使用 xslt 从 xml 文档中过滤掉任意节点

XSLT 替换属性值和文本节点中的文本

如何获取具有相同名称的元素并根据 XSLT 中的子节点值对它们进行排序

使用 XSLT 重命名节点