XSLT 1.0实现先排内部Color再排Material的顺序排序需求
在XSLT 1.0中实现“先排子列表再排父列表”的方案
完全可以在XSLT 1.0中实现你的需求,核心思路是先为每个父节点(Material)计算出排序后的子节点(Color)的关键特征,再用该特征作为父节点的排序依据,同时单独处理子节点的排序输出。
假设你的XML结构如下
<Shirt> <Material name="Polyester"> <Color>Bcolor</Color> <Color>Acolor</Color> </Material> <Material name="Cotton"> <Color>Ccolor</Color> <Color>Acolor</Color> </Material> <Material name="Wool"> <Color>Dcolor</Color> </Material> </Shirt>
实现代码
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml" indent="yes"/> <xsl:template match="/Shirt"> <Shirt> <!-- 遍历并排序Material节点 --> <xsl:for-each select="Material"> <!-- 第一步:获取当前Material下排序后的第一个Color值 --> <xsl:variable name="sorted-first-color"> <xsl:for-each select="Color"> <xsl:sort select="." data-type="text" order="ascending"/> <xsl:if test="position() = 1"> <xsl:value-of select="."/> </xsl:if> </xsl:for-each> </xsl:variable> <!-- 第二步:基于排序后的Color特征排序Material --> <!-- 优先把排序后首Color为"Acolor"的Material排到最前 --> <xsl:sort select="$sorted-first-color = 'Acolor'" data-type="boolean" order="descending"/> <!-- 再按排序后的首Color字母顺序排序 --> <xsl:sort select="$sorted-first-color" data-type="text" order="ascending"/> <!-- 最后按Material名称排序 --> <xsl:sort select="@name" data-type="text" order="ascending"/> <!-- 输出Material节点 --> <Material> <xsl:copy-of select="@name"/> <!-- 输出当前Material下排序后的Color列表 --> <xsl:for-each select="Color"> <xsl:sort select="." data-type="text" order="ascending"/> <xsl:copy-of select="."/> </xsl:for-each> </Material> </xsl:for-each> </Shirt> </xsl:template> </xsl:stylesheet>
代码说明
- 子列表(Color)排序:在每个Material内部,通过
<xsl:for-each>结合<xsl:sort>对Color节点按字母顺序排序后输出,确保子列表有序。 - 父列表(Material)排序:
- 先通过嵌套的
<xsl:for-each>获取当前Material下排序后的第一个Color值,存入变量sorted-first-color; - 以此变量为依据,优先将首Color为"Acolor"的Material排到首位,再按首Color字母顺序、Material名称依次排序。
- 先通过嵌套的
该方案完全基于XSLT 1.0原生语法实现,无需扩展函数,能精准满足你“先排Color列表,再基于排序后的Color排序Material”的需求,最终会让包含"Acolor"的"Cotton"Material排在输出结果的最前面。
内容的提问来源于stack exchange,提问作者Gab
相关产品推荐
相关产品推荐

