包装有序的节点列表

时间:2013-05-24 09:43:06

标签: xslt xslt-2.0

您好我有一个xml文档,如下所示:

<a> <!-- Several nodes "a" with the same structure for children -->
    <b>12</b>
    <c>12</c>
    <d>12</d>
    <e>12</e>
    <f>12</f>
    <g>12</g>
</a>

我正在尝试使用xslt 2.0获取以下文档

<a>
    <b>12</b>
    <c>12</c>
    <wrap>
        <d>12</d>        
        <e>12</e>
        <f>12</f>
        <g>12</g>
    </wrap>
</a>

我用

启动了我的xsl文件
<xsl:template match="node()|@*">
    <xsl:copy>
        <xsl:apply-templates select="node()|@*"/>
    </xsl:copy>
</xsl:template>

并在几个案例中更改了它,例如替换字符串部分,过滤一些节点等。 但我坚持“选择四个连续节点”,任何关于如何实现包装的线索?

2 个答案:

答案 0 :(得分:2)

如果你的所有a元素都是真正完全相同的结构,那么最简单的就是蛮力

<xsl:template match="a">
  <xsl:copy>
    <xsl:apply-templates select="b | c" />
    <wrap>
      <xsl:apply-templates select="d | e | f | g" />
    </wrap>
  </xsl:copy>
</xsl:template>

或者如果你想变得有点聪明

    <wrap>
      <xsl:apply-templates select="* except (b | c)" />
    </wrap>

如果你想总是“包裹”a的最后四个子元素,那么怎么样

<xsl:template match="a">
  <xsl:variable name="lastFour" select="*[position() &gt; (last() - 4)]" />
  <xsl:copy>
    <xsl:apply-templates select="* except $lastFour" />
    <wrap>
      <xsl:apply-templates select="$lastFour" />
    </wrap>
  </xsl:copy>
</xsl:template>

答案 1 :(得分:1)

使用XSLT 2.0,您还可以使用for-each-group group-adjacent

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

    <xsl:output indent="yes"/>

    <xsl:template match="node()|@*">
        <xsl:copy>
            <xsl:apply-templates select="node()|@*"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="a">
      <xsl:copy>
        <xsl:for-each-group select="*" group-adjacent="boolean(self::d | self::e | self::f | self::g)">
          <xsl:choose>
            <xsl:when test="current-grouping-key()">
              <wrap>
                <xsl:apply-templates select="current-group()"/>
              </wrap>
            </xsl:when>
            <xsl:otherwise>
              <xsl:apply-templates select="current-group()"/>
            </xsl:otherwise>
          </xsl:choose>
        </xsl:for-each-group>
      </xsl:copy>
    </xsl:template>

    </xsl:stylesheet>