XSLT 转换 XML:选择 uuid 并按顺序排序

Posted

技术标签:

【中文标题】XSLT 转换 XML:选择 uuid 并按顺序排序【英文标题】:XSLT to transform XML: selecting uuids and sorting in order 【发布时间】:2021-08-07 00:46:54 【问题描述】:
   ## 

我确实有多个 uuid 分组在不同元素下的大型 xml 文件。我希望它们在每个组中进行排序。有人可以在此发表他们的想法吗?----------

这是用于格式化的xslt文件

预期输出:对文件中的所有 uid 进行排序

【问题讨论】:

XSLT 和 XPath 具有排序功能。你被困在哪里了?至少提供格式良好的 XML 输入并发布您迄今为止尝试过的代码。 这是我正在使用的 xslt 文件,我需要知道需要提供数据类型才能对 uuid 进行排序。 【参考方案1】:

如果要对 uuid 元素进行排序,则必须从其父 uuids 元素的上下文中对它们应用排序指令 - 而不是从非上下文的上下文中对不存在的 test 元素应用排序指令- 现有的table 元素。

另外,UUID 不是数字,将它们按数字排序是没有意义的。事实上,根本不清楚对它们进行排序有什么意义,因为它们在定义上毫无意义。不过,如果你愿意,你可以这样做:

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

<!-- identity transform -->
<xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
</xsl:template>

<xsl:template match="uuids">
    <xsl:copy>
        <xsl:apply-templates select="uuid">
            <xsl:sort select="."/>
        </xsl:apply-templates>
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>

演示:https://xsltfiddle.liberty-development.net/6qaHaQP

【讨论】:

感谢您的快速回答。我也可以知道我们该如何排序.... 1chistory>2 使您的模板匹配history。使用&lt;xsl:apply-templates select="historyInfo"&gt;&lt;xsl:sort select="@versionUuid"/&gt; P.S.请不要在 cmets 中发布代码。编辑您的问题或发布新问题。 谢谢。我已经尝试了上述更改。但它不工作。我刚刚更新了问题。你能看一下代码吗? 请再次编辑您的问题并显示 (1) 格式良好的 XML 输入,(2) 您当前的 XSLT 尝试和 (3) 预期输出。 --- 此外,您所做的更改毫无意义。我建议您在此处发布之前花一个小时学习 XPath/XSLT 教程。否则你将无法理解给你的答案并应用它们。【参考方案2】:

你可以这样做:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="2.0">
    
    <xsl:output method="xml" indent="yes"/>

    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>
    
    <!-- If the uuid elements are not always in a uuids element, can replace with *[uuid] -->
    <xsl:template match="uuids">
        <xsl:copy>
            <xsl:for-each select="uuid">
                <xsl:sort select="." data-type="text" order="ascending"/>
                <xsl:copy-of select="."/>
            </xsl:for-each>
        </xsl:copy>
    </xsl:template>
  
</xsl:stylesheet>

在这里查看它的工作原理:https://xsltfiddle.liberty-development.net/93wniTR

【讨论】:

感谢您的快速回答。我也可以知道我们该如何排序....&lt;history&gt; &lt;historyInfo versionUuid="_a-0000e3b5-23f2-8000-9ba7-011c48011c48_237484"/&gt; &lt;historyInfo versionUuid="_a-0000e3e5-e568-8000-9ba9-011c48011c48_243829"/&gt; &lt;historyInfo versionUuid="_a-0000e3e5-e568-8000-9ba9-011c48011c48_250806"/&gt; &lt;historyInfo versionUuid="_a-0000e3e5-e568-8000-9ba9-011c48011c48_252670"/&gt; &lt;/history&gt;【参考方案3】:

这是运行良好的 .xslt 模板

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

<!-- identity transform -->
<xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
</xsl:template>

<xsl:template match="uuids">
    <xsl:copy>
        <xsl:apply-templates select="uuid">
            <xsl:sort select="."/>
        </xsl:apply-templates>
    </xsl:copy>
</xsl:template>

<xsl:template match="history">
    <xsl:copy>
        <xsl:apply-templates select="historyInfo">
            <xsl:sort select="@versionUuid"/>
        </xsl:apply-templates>
    </xsl:copy>
</xsl:template>
</xsl:stylesheet>

【讨论】:

以上是关于XSLT 转换 XML:选择 uuid 并按顺序排序的主要内容,如果未能解决你的问题,请参考以下文章

使用 CDATA 元素对 xml 中的 uuid 进行排序的 xslt 模板

无法使用 XSLT 转换 XML

XSLT转换无法模板匹配

在未指定出现顺序时处理 XSLT 中的子标记

XSLT 转换在我删除根节点之前不起作用

XSLT 转换在我删除根节点之前不起作用