我是XSLT的菜鸟,所以请原谅我的无知...我试图按属性值和标签名称对一个简单的XML文件进行排序,但我很难访问该属性的值.这是一个完整的例子:
<a>
<b attribute="e"></b>
<b attribute="b"></b>
<d attribute="a"></d>
<c></c>
</a>
Run Code Online (Sandbox Code Playgroud)
预期的结果是:
<a>
<b attribute="b"></b>
<b attribute="e"></b>
<c></c>
<d attribute="a"></d>
</a>
Run Code Online (Sandbox Code Playgroud)
我试图解决这个问题:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes" />
<xsl:strip-space elements="*" />
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="@*">
<xsl:sort select="."/>
</xsl:apply-templates>
<xsl:apply-templates select="node()">
<xsl:sort select="name()"/>
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Run Code Online (Sandbox Code Playgroud)
这显然根本不起作用......
在上面的例子中,我想按照它们的属性值对b标签进行排序,但是你可以看到d标签没有按属性值排序,因为它是另一个标签名称......
我想知道使用XSLT是否可行......你有什么想法吗?
提前致谢.
UPDATE ----------------------
我尝试了似乎工作正常并且看起来非常简单的andyb解决方案,但我对此解决方案有另一个问题.
假设我有这个XML:
<a>
<b attribute="e" optionalAttr="fg"></b>
<b attribute="b"></b>
<d attribute="a"></d>
<c></c>
</a>
Run Code Online (Sandbox Code Playgroud)
我为b标签添加了一个可选参数.应用andyb解决方案将忽略可选参数,因为它在模板中不匹配.结果如下:
<a>
<b attribute="b"></b>
<b attribute="e"></b>
<c></c>
<d attribute="a"></d>
</a>
Run Code Online (Sandbox Code Playgroud)
而不是以下是我所期望的:
<a>
<b attribute="b"></b>
<b attribute="e" optionalAttr="fg"></b>
<c></c>
<d attribute="a"></d>
</a>
Run Code Online (Sandbox Code Playgroud)
你有什么主意吗?提前致谢.
您可以使用多个xsl:sort指令,例如:
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*">
<xsl:sort select="name()" />
<xsl:sort select="@*" />
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
Run Code Online (Sandbox Code Playgroud)
由于默认数据类型为"text",默认顺序为"ascending",因此提供了所需的输出.
编辑
这很奇怪,因为对于以下XML:
<a>
<b attribute="e" optionalAttr="fg"></b>
<b attribute="b"></b>
<d attribute="a"></d>
<c></c>
</a>
Run Code Online (Sandbox Code Playgroud)
和上面的XSL,我得到这个结果:
<a>
<b attribute="b"></b>
<b attribute="e" optionalAttr="fg"></b>
<c></c>
<d attribute="a"></d>
</a>
Run Code Online (Sandbox Code Playgroud)
这包括所需的可选属性,但顺序与编辑的问题中的XML不同(<c></c>位于不同的位置).
此XSLT 2.0转换按元素名称和多个属性名称和值执行排序:
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:my="my:my">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*">
<xsl:sort select="name()" />
<xsl:sort select="my:attributeScore(.)" />
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
<xsl:function name="my:attributeScore" as="xs:string">
<xsl:param name="pThis" as="node()"/>
<xsl:variable name="vScore">
<xsl:for-each select="$pThis/@*">
<xsl:sort select="name()"/>
<xsl:value-of select="concat(name(),'+',.)"/>
</xsl:for-each>
<xsl:text>|</xsl:text>
</xsl:variable>
<xsl:sequence select="string-join($vScore, '')"/>
</xsl:function>
</xsl:stylesheet>
Run Code Online (Sandbox Code Playgroud)
当应用于此XML文档(提供的文档,但添加了多个属性)时:
<a>
<b attribute="e" x="y"></b>
<b attribute="e" x="x"></b>
<b attribute="b"></b>
<d attribute="a"></d>
<c></c>
</a>
Run Code Online (Sandbox Code Playgroud)
生成正确排序的结果:
<a>
<b attribute="b"/>
<b attribute="e" x="x"/>
<b attribute="e" x="y"/>
<c/>
<d attribute="a"/>
</a>
Run Code Online (Sandbox Code Playgroud)