XSLT 根据节点的位置重复打印节点的值

XSLT to print values of a node based on its position repetitively

我必须在 xslt 1.0 或 xslt 2.0 中转换此示例 xml 来源XML

<root>
    <group>
        <subgroup>
            <name>AAA1</name>
        </subgroup>
        <subgroup>
            <name>AAA2</name>
        </subgroup>
        <subgroup>
            <name>AAA3</name>
       </subgroup>
    </group>
 <group>
        <subgroup>
            <name>BB1</name>
        </subgroup>
        <subgroup>
            <name>BB2</name>
        </subgroup>
        <subgroup>
            <name>BB3</name>
       </subgroup>
    </group>
</root>

需要XML输出

<?xml version="1.0" encoding="UTF-8"?>
<root>
  <group>AAA1|BB1|AAA2|BB2|AAA3|BB3</group>
</root>

我尝试了以下 xslt:

XSLT

    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" indent="yes" />
    <xsl:template match="root">
    <root>
      <group>
       <xsl:for-each select="group">
          <xsl:for-each select="subgroup">
            <xsl:choose>
            <xsl:when test="position() != last()">
            <xsl:value-of select="name" /><xsl:text>|</xsl:text>
            </xsl:when>
            <xsl:otherwise>
               <xsl:value-of select="name" />
            </xsl:otherwise>
             </xsl:choose> 
          </xsl:for-each>
       </xsl:for-each>
       </group>
    </root>
</xsl:template>
</xsl:stylesheet>

电流输出

<?xml version="1.0" encoding="UTF-8"?>
<root>
<group>AAA1|AAA2|AAA3BB1|BB2|BB3</group>
</root>

我该怎么做?我应该创建一个模板并递归调用它吗?

您只需要处理 spec 组元素中的 一个 组,并按位置从另一组中拉出相应的 spec

<root>
  <group>
    <xsl:for-each select="group[1]/spec">
      <xsl:variable name="pos" select="position()"/>
      <xsl:for-each select="../../group">
        <!-- put a | in front of everything but the first spec in the first group -->
        <xsl:if test="$pos &gt; 1 or position() &gt; 1">|</xsl:if>
        <xsl:value-of select="spec[$pos]/name" />
      </xsl:for-each>
    </xsl:for-each>
  </group>
</root>

XSLT 2.0 版本:在 2.0 中,您可以使用单个 value-of:

<group>
  <xsl:value-of select="for $n in 1 to count(group[1]/spec)
                        return (group/spec[$n]/name)" separator="|" />
</group>

想到这个:

选取除第一组以外的所有其他组,然后迭代第一组的所有规格,同时从所有其他组选取相应的规格

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" indent="yes" />
  <xsl:template match="root">
    <root>
      <group>
        <xsl:variable name="firstExcludeGroups" select="//group[position()!=1]"/>
        <xsl:variable name="firstGroup" select="//group[position()=1]"/>
        <xsl:for-each select="$firstGroup/spec">
          <xsl:value-of select="name"/>
          <xsl:text>|</xsl:text>
          <xsl:variable name="curPosition" select="position()"/>
          <xsl:for-each select="$firstExcludeGroups/spec">
            <xsl:if test="$curPosition=position()">
              <xsl:value-of select="name"/>
            </xsl:if>
          </xsl:for-each>
        </xsl:for-each>
      </group>
    </root>
  </xsl:template>
</xsl:stylesheet>