我有一个xml,如:
<PersonList>
<Person>
<Name>Smith</Name>
<Role>5</Role>
</Person>
<Person>
<Name>Star</Name>
<Role>3</Role>
</Person>
<Person>
<Name>Wars</Name>
<Role>1</Role>
</Person>
</PersonList>
在xslt中我想以这样的方式排序:如果有一个角色1,这应该是列表中的第一个Person。 其余人员应按名称按字母顺序排序。
提前致谢。
答案 0 :(得分:3)
以这种方式尝试:
XSLT 1.0
<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="/PersonList">
<xsl:copy>
<xsl:apply-templates select="Person">
<xsl:sort select="number(Role=1)" data-type="number" order="descending"/>
<xsl:sort select="Name" data-type="text" order="ascending"/>
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
或者,如果您愿意:
...
<xsl:template match="/PersonList">
<xsl:copy>
<xsl:apply-templates select="Person[Role=1]"/>
<xsl:apply-templates select="Person[not(Role=1)]">
<xsl:sort select="Name" data-type="text" order="ascending"/>
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
...
表达式Role=1
返回布尔结果。但是,XSLT 1.0的xsl:sort
指令只能按文本或数字排序。因此,结果必须先转换为字符串或数字,然后才能用于排序。
我更喜欢将布尔值转换为数字,因为在阅读代码时,预期的顺序更容易理解。
出于同样的原因,我更愿意明确说明data-type
和order
,即使它们分别是“text”和“ascending”的默认值。
在任何情况下,如果一个人更喜欢按文本排序,那么所需的过程在复杂性方面相同 1 :
<xsl:sort select="not(Role=1)"/>
只是简称:
<xsl:sort select="string(not(Role=1))" data-type="text" order="ascending"/>
与以下内容相同:
<xsl:sort select="string(Role=1)" data-type="text" order="descending"/>
这三者之间的唯一区别在于代码可读性。
(1)有人可能会争辩说,数字排序比按字母顺序排序更有效,但我不知道这是事实,所以我不会。
注意:强>
这些差异很小,很大程度上取决于个人偏好。
答案 1 :(得分:2)
更简单,更简短的解决方案 - 无需数字排序:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/*">
<xsl:copy>
<xsl:apply-templates select="*">
<xsl:sort select="not(Role=1)"/>
<xsl:sort select="Name"/>
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
<强>解释强>:
对布尔值进行排序时,false()
true()
之前会出现。
多键排序