我有一个巨大的XML格式的配置文件.系统不关心标签的顺序,但我们人类做的!(主要是为了版本比较的目的.)我已经收到了下面的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>
Run Code Online (Sandbox Code Playgroud)
我希望通过其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>
Run Code Online (Sandbox Code Playgroud)
我的数据看起来与此类似,问题是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>
Run Code Online (Sandbox Code Playgroud)
更新:
在Vincent的帮助下,我创建了一个适合我们目的的分类.这里是.
这是一个假设您的数据中没有任何混合内容的响应。它仅考虑前两个步骤(@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>
Run Code Online (Sandbox Code Playgroud)
请注意,代码在具有相同值的组上进行迭代,因此,如果元素上不存在属性,则这些元素将被分组在一起。
我将以下 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>
Run Code Online (Sandbox Code Playgroud)
我有以下结果:
<?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>
Run Code Online (Sandbox Code Playgroud)