gpt4 book ai didi

XSLT 对多个属性的值进行排序

转载 作者:行者123 更新时间:2023-12-02 11:42:01 25 4
gpt4 key购买 nike

我有一个巨大的 XML 格式的配置文件。系统不关心标签的顺序,但我们人类关心! (主要是为了版本比较的目的。)I already received下面的 XSLT 运行良好,但我发现它还不够。

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="*">
<xsl:copy>
<xsl:copy-of select="@*"/>
<xsl:apply-templates>
<xsl:sort select="(@name, name())[1]"/>
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>

我想按其 name 属性的值对所有标签进行递归排序(这有效!),但由于该属性并不总是存在,因此它还必须按其他属性,其中任何属性可能出现也可能不出现在任何给定元素中。

我对 XSLT 的了解基本上为零,所以我正在尝试。我已经将上面的内容修改为这个,但它没有按预期工作。这个结果似乎与上面的相同。

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="*">
<xsl:copy>
<xsl:copy-of select="@*"/>
<xsl:apply-templates>
<xsl:sort select="@name"/>
<xsl:sort select="@row" data-type="number"/>
<xsl:sort select="@col" data-type="number"/>
<xsl:sort select="@sequence" data-type="number"/>
<xsl:sort select="@tabindex" data-type="number"/>
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>

我的数据看起来与此类似,问题是 cell 元素根本没有排序(在其 grid 组内),因为它们没有 name 属性。这就是为什么我想扩展排序逻辑以使用 name 属性(如果存在),否则应该使用 tabindex 等附加属性来完成排序。在任何给定的组中,可以假设存在相同的属性。

<sections>
<section name="SomeList">
<caption>
<![CDATA[Candidates]]>
</caption>
...
<parameters>
<parameter name="pageSize">
<![CDATA[50]]>
</parameter>
</parameters>
...
<grid>
<cell row="0" col="7" tabindex="9" colspan="10">
<field name="Entered" />
</cell>
</grid>
</section>
</sections>

更新:
在 Vincent 的大力帮助下,我创建了一个足以满足我们目的的排序方法。 Here it is.

最佳答案

这是一个假设您的数据中没有任何混合内容的响应。它仅考虑前两个步骤(@name 和 @col),您可以适应进一步的步骤。也许可以使用递归命名模板重写它,该模板将排序参数列表作为输入。如果我的 XSLT 不适合您,您能否提供一个 XML 示例。

XSLT 2.0 示例:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:template match="*">
<xsl:copy>
<xsl:copy-of select="@*"/>
<xsl:for-each-group select="*" group-by="if (exists(@name)) then @name else ''">
<xsl:sort select="current-grouping-key()" data-type="text"/>
<xsl:for-each-group select="current-group()" group-by="if (exists(@row)) then @row else -1">
<xsl:sort select="current-grouping-key()" data-type="number"/>
<xsl:apply-templates select="current-group()"/>
</xsl:for-each-group>
</xsl:for-each-group>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>

请注意,代码会在具有相同值的组上进行迭代,因此,如果元素上不存在属性,则这些元素将被分组在一起。

我将以下 XML 作为输入:

<?xml version="1.0" encoding="UTF-8"?>
<items>
<item row="5" col="9"></item>
<item name="d" row="20" col="12" tabindex="" sequence=""></item>
<item row="1" col="5" ></item>
<item name="d" row="5" col="6" ></item>
<item name="a" row="7" col="8" ></item>
<item name="s" row="1" col="5" ></item>
<item name="c" row="5" col="9"></item>
<item row="2" col="5" ></item>
<item row="20" col="9"></item>
<item row="0" col="9"></item>
<item name="s" row="2" col="10" tabindex="" sequence=""></item>
<item name="z" row="8" col="15" tabindex="" sequence=""></item>
</items>

我得到以下结果:

<?xml version="1.0" encoding="UTF-8"?>
<items>
<item row="0" col="9"/>
<item row="1" col="5"/>
<item row="2" col="5"/>
<item row="5" col="9"/>
<item row="20" col="9"/>
<item name="a" row="7" col="8"/>
<item name="c" row="5" col="9"/>
<item name="d" row="5" col="6"/>
<item name="d" row="20" col="12" tabindex="" sequence=""/>
<item name="s" row="1" col="5"/>
<item name="s" row="2" col="10" tabindex="" sequence=""/>
<item name="z" row="8" col="15" tabindex="" sequence=""/>
</items>

关于XSLT 对多个属性的值进行排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8267147/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com