如何使用xsl:iterate识别可以制作成非空元素的元素对

时间:2016-10-06 13:05:57

标签: xslt xslt-3.0

鉴于这个XML,我需要填充" flag-end"使用正确的@associatedId元素,以便我可以使用xsl:iterate从标志中重新创建元素。我知道如何创建元素,我能解释的是如何在每个标志端正确填充@associatedId。 (由于我们使用的第三方软件,这是必要的。我始终保证有相同数量的开始和结束标志,并且正确数量的结束标志将遵循正确数量的起始标志。)

    <outer>
        hello
        <flag-start associatedId="test3"/>
        <flag-start associatedId="test"/>
        <span>wor<b>---</b>ld</span>
        <flag-start associatedId="test4"/>
        <flag-end/>
        <flag-start associatedId="test2"/>
        <flag-end/>
        <flag-end/>
        <flag-end/>
        <flag-start associatedId="test5"/>
        <flag-end/>
        some more text
    </outer>

这是所需的XML输出:

    <outer>
        hello
        <flag-start associatedId="test3"/>
        <flag-start associatedId="test"/>
        <span>wor<b>---</b>ld</span>
        <flag-start associatedId="test4"/>
        <flag-end associatedId="test4"/>
        <flag-start associatedId="test2"/>
        <flag-end associatedId="test2"/>
        <flag-end associatedId="test"/>
        <flag-end associatedId="test3"/>
        <flag-start associatedId="test5"/>
        <flag-end associatedId="test5"/>
        some more text
    </outer>

1 个答案:

答案 0 :(得分:1)

这样的事情:

<xsl:iterate select="*">
  <xsl:param name="stack" select="()"/>
  <xsl:choose>
    <xsl:when test="self::flag-start">
      <xsl:copy-of select="."/>
      <xsl:next-iteration>
        <xsl:with-param name="stack" select="@associatedID, $stack"/>
      </xsl:next-iteration>
    </xsl:when>
    <xsl:when test="self::flag-end">
      <xsl:copy>
        <xsl:attribute name="associatedId" select="head($stack)"/>
      </xsl:copy>
      <xsl:next-iteration>
        <xsl:with-param name="stack" select="tail($stack)"/>
      </xsl:next-iteration>
    </xsl:when>
    <xsl:otherwise>
      <xsl:copy-of select="."/>
    </xsl:otherwise>
  </xsl:choose>
</xsl:iterate>

未经测试。假设可以信任数据是合理的。