如何编写XSL样式表调整XML元素输出顺序为b、c、a?
问题描述
给定如下XML片段:
<?xml version="1.0" encoding="UTF-8"?> <root> <a>This is A</a> <b>This is B</b> <c>This is C</c> </root>
需要编写XSL样式表将子元素按b、c、a的顺序输出(实际场景中元素顺序无规律,无法通过排序实现)。尝试了以下代码后,输出仍保持原文档顺序a、b、c:
<xsl:template match="/root"> <output> <xsl:for-each select="b | c | a"> <xsl:copy-of select="." /> </xsl:for-each> </output> </xsl:template>
想知道是否存在比逐个重构元素(如下代码)更优的实现方式:
<xsl:template match="/root"> <output> <b><xsl:value-of select="b" /></b> <c><xsl:value-of select="c" /></c> <a><xsl:value-of select="a" /></a> </output> </xsl:template>
解决方案
1. XSLT 1.0 环境
你之前用b | c | a的问题在于,XSLT 1.0中的节点集会自动按文档顺序重新排列,所以不管你写的顺序是什么,最终都会回到原文档的顺序。
更优的写法是直接逐个复制指定元素,不用重构标签:
<xsl:template match="/root"> <output> <xsl:copy-of select="b"/> <xsl:copy-of select="c"/> <xsl:copy-of select="a"/> </output> </xsl:template>
这种方式比逐个重构元素更好,因为它会完整复制元素的所有属性、子节点(如果有的话),而不仅仅是文本内容,同时写法也更简洁。
2. XSLT 2.0 及以上环境
如果使用的是XSLT 2.0或更高版本,可以直接使用序列语法,括号包裹的序列会严格按照你指定的顺序输出,不会自动重排:
<xsl:template match="/root"> <output> <xsl:copy-of select="(b, c, a)"/> </output> </xsl:template>
这种写法最简洁,也能保证顺序正确。
内容的提问来源于stack exchange,提问作者Mike Henderson
相关产品推荐
相关产品推荐

