使用XSLT 1.0将重复XML标签归置到同一位置的需求
使用XSLT 1.0将重复同类型标签集中排列
输入XML
<?xml version="1.0" encoding="UTF-8"?> <root> <tag1>1</tag1> <tag1_1>not repeating</tag1_1> <tag2>2</tag2> <tag3>3</tag3> <tag4>4</tag4> <tag5>5</tag5> <tag6>6</tag6> <tag2>2</tag2> <tag3>3</tag3> <tag1>1</tag1> <tag4>4</tag4> <tag1>1</tag1> <tag3>3</tag3> <tag2>2</tag2> <tag4>4</tag4> <tag4>4</tag4> <tag2>2</tag2> <tag1>1</tag1> <tag3>3</tag3> </root>
期望输出XML
<?xml version="1.0" encoding="UTF-8"?> <root> <tag1>1</tag1> <tag1_1>not repeating</tag1_1> <tag2>2</tag2> <tag3>3</tag3> <tag4>4</tag4> <tag5>5</tag5> <tag6>6</tag6> <tag1>1</tag1> <tag2>2</tag2> <tag3>3</tag3> <tag4>4</tag4> <tag1>1</tag1> <tag2>2</tag2> <tag3>3</tag3> <tag4>4</tag4> <tag1>1</tag1> <tag2>2</tag2> <tag3>3</tag3> <tag4>4</tag4> </root>
XSLT 1.0解决方案
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml" indent="yes" encoding="UTF-8"/> <!-- 按元素名称分组,便于统计和获取实例 --> <xsl:key name="elem-by-name" match="root/*" use="local-name()"/> <!-- 获取所有唯一标签名,按首次出现顺序排列 --> <xsl:variable name="first-occurrence-names" select="root/*[generate-id() = generate-id(key('elem-by-name', local-name())[1])]/local-name()"/> <!-- 计算出现次数最多的标签的重复次数 --> <xsl:variable name="max-repeat-count"> <xsl:for-each select="root/*[generate-id() = generate-id(key('elem-by-name', local-name())[1])]"> <xsl:sort select="count(key('elem-by-name', local-name()))" data-type="number" order="descending"/> <xsl:if test="position() = 1"> <xsl:value-of select="count(key('elem-by-name', local-name()))"/> </xsl:if> </xsl:for-each> </xsl:variable> <xsl:template match="/"> <root> <!-- 先输出每个标签的第一个实例 --> <xsl:for-each select="$first-occurrence-names"> <xsl:copy-of select="key('elem-by-name', .)[1]"/> </xsl:for-each> <!-- 循环输出后续的重复实例,按tag1、tag2、tag3、tag4的顺序分组 --> <xsl:for-each select="2 to $max-repeat-count"> <xsl:variable name="current-index" select="."/> <xsl:for-each select="'tag1', 'tag2', 'tag3', 'tag4'"> <xsl:if test="count(key('elem-by-name', .)) >= $current-index"> <xsl:copy-of select="key('elem-by-name', .)[$current-index]"/> </xsl:if> </xsl:for-each> </xsl:for-each> </root> </xsl:template> </xsl:stylesheet>
工作原理
- 分组统计:通过
<xsl:key>按元素名称分组,快速获取每个标签的所有实例和出现次数。 - 保留首次顺序:先输出所有标签的第一个实例,确保非重复标签(如
tag1_1、tag5、tag6)只出现一次且位置不变。 - 循环输出重复项:根据最大重复次数,从第2个实例开始,按
tag1→tag2→tag3→tag4的顺序依次输出对应索引的实例,实现集中排列的效果。
内容的提问来源于stack exchange,提问作者RaviRaj
相关产品推荐
相关产品推荐

