我有这个xml代码:
<items>
<item name="xyz_low" />
<item name="xyz_hight" />
<item name="xyz_medium" />
<item name="abc_medium" />
<item name="abc_low" />
<item name="abc_hight" />
</items>
我想得到类似的东西:
<items>
<item name="xyz_hight" />
<item name="xyz_medium" />
<item name="xyz_low" />
<item name="abc_hight" />
<item name="abc_medium" />
<item name="abc_low" />
</items>
排序仅在具有相同属性名称的第一部分(下划线之前的部分)的标记之间发生。订单是高,中,低。
我看ends-with
,但这对我来说还不够,因为我不知道第一部分是xyz,abc还是别的。
我不需要对第一部分进行排序:我只想以同样的方式对项目标签组中的后缀进行排序。
是否可以选择不同的方法?
答案 0 :(得分:2)
要按照这样的固定顺序对项目进行排序,您可以使用这样的技巧:为排序顺序定义变量
<xsl:variable name="sortOrder" select="'|hight|medium|low|'" />
现在您可以使用
进行排序<xsl:sort select="string-length(substring-before($sortOrder, concat('|', value, '|')))"
data-type="number" />
您需要的value
。如果value
为“hight”,则substring-before
的长度为0,“medium”的长度为6,等等。
这是一个XSLT 2.0模板,它会做你想要的事情,假设变量定义
<xsl:template match="items">
<items>
<xsl:for-each-group select="item" group-adjacent="substring-before(@name, '_')">
<xsl:perform-sort select="current-group()">
<xsl:sort select="string-length(substring-before($sortOrder,
concat('|', substring-after(@name, '_'), '|')))"
data-type="number" />
</xsl:perform-sort>
</xsl:for-each-group>
</items>
</xsl:template>
要在XSLT 1.0中做同样的事情,你需要做一个Muenchian分组技巧
<xsl:key name="itemByPrefix" match="item" use="substring-before(@name, '_')" />
然后在模板中
<xsl:template match="items">
<items>
<xsl:for-each select="item[generate-id() = generate-id(
key('itemByPrefix', substring-before(@name, '_'))[1])]">
<xsl:for-each select="key('itemByPrefix', substring-before(@name, '_'))">
<xsl:sort select="string-length(substring-before($sortOrder,
concat('|', substring-after(@name, '_'), '|')))"
data-type="number" />
<xsl:copy-of select="." />
</xsl:for-each>
</xsl:for-each>
</items>
</xsl:template>
(如果源文档中有几个不同的items
集合,XSLT 2.0版本仍然有效,在这种情况下,XSLT 1.0版本会变得更加混乱。“