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

How to identify pairs of elements that can then be made into non-empty elements using xsl:iterate

鉴于此 XML,我需要使用正确的 @associatedId 填充 "flag-end" 元素,以便我可以使用 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>

像这样:

<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>

未测试。假设数据是可靠的。