如何合并连续找到的同名元素

时间:2015-04-22 16:23:29

标签: xml xslt xslt-2.0

请建议如何合并连续出现的同名[元素mi]元素。只有元素 mi [没有任何属性]才需要合并。 元素MI可能有任何父母。

XML:

<article>
    <math>
        <mtext>one</mtext>
        <mi>i</mi>
        <mi>n</mi>
        <mi>s</mi>
        <mi>t</mi>
        <mtext>The</mtext>
        <mi>s</mi>
        <mi>m</mi>
        <mrow>
            <mi>a</mi>
            <mi>l</mi>
            <mi>l</mi>
        </mrow>
        <mi>y</mi>
        <mn>8</mn>
        <mi>z</mi>
    </math>
</article>

XSLT:

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

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

    <xsl:template match="mi">
        <xsl:choose>
            <xsl:when test="not(preceding-sibling::*[name()='mi'][1]) and not(following-sibling::*[name()='mi'][1])">
                <xsl:copy><xsl:apply-templates select="@* | node()"/></xsl:copy>
            </xsl:when>

            <xsl:when test="following-sibling::*[1][name()='mi']">
                <xsl:variable name="varcnt">
                    <xsl:value-of select="count(following-sibling::*)"/>
                </xsl:variable>
                <xsl:copy>
                <xsl:for-each select="1 to number($varcnt)">
                    <xsl:if test="name()='mi'">
                    <xsl:apply-templates/>
                    </xsl:if>
                </xsl:for-each>
                </xsl:copy>
            </xsl:when>
            <xsl:otherwise><xsl:copy><xsl:apply-templates select="@* | node()"/></xsl:copy></xsl:otherwise>
        </xsl:choose>
    </xsl:template>
</xsl:stylesheet>

必填项:

<article>
    <math>
        <mtext>one</mtext>
        <mi variant="italic">inst</mi>
        <mtext>The</mtext>
        <mi variant="italic">sm</mi>
        <mrow>
            <mi variant="italic">all</mi>
        </mrow>
        <mi>y</mi>
        <mn>8</mn>
        <mi>z</mi>
    </math>
</article>

1 个答案:

答案 0 :(得分:1)

使用for-each-group group-adjacent="boolean(self::mi)",如

<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="*[mi]">
      <xsl:copy>
        <xsl:for-each-group select="*" group-adjacent="boolean(self::mi)">
          <xsl:choose>
            <xsl:when test="current-grouping-key() and count(current-group()) gt 1">
              <mi variant="italic"><xsl:apply-templates select="current-group()/node()"/></mi>
            </xsl:when>
            <xsl:otherwise>
              <xsl:apply-templates select="current-group()"/>
            </xsl:otherwise>
          </xsl:choose>
        </xsl:for-each-group>
      </xsl:copy>
    </xsl:template>

</xsl:stylesheet>