将多个元素合并为单个元素

时间:2016-12-13 07:03:30

标签: xslt-2.0

我需要建议将多个元素和兄弟文本节点合并为一个元素。请参考下面提到的示例中的外部参照元素。

Input: <section><p>These pages are all about XSLT, an XML-based language <xref ref-type="bibr" rid="r1">1</xref><xref ref-type="bibr" rid="r2"/>--<xref ref-type="bibr" rid="r3">3</xref> for translating one set of XML into another set of XML, <xref ref-type="bibr" rid="r3">3</xref>, <xref ref-type="bibr" rid="r5">5</xref><xref ref-type="bibr" rid="r6"/>--<xref ref-type="bibr" rid="r7">7</xref> or into HTML. Of course, there are all sorts of other pages  <xref ref-type="bibr" rid="r1">7</xref>, <xref ref-type="bibr" rid="r3">8</xref>  around that cover XSLT. <xref ref-type="bibr" rid="r12">12</xref>, <xref ref-type="bibr" rid="r15">15</xref><xref ref-type="bibr" rid="r16"/><xref ref-type="bibr" rid="r17"/><xref ref-type="bibr" rid="r18"/><xref ref-type="bibr" rid="r19"/>--<xref ref-type="bibr" rid="r20">20</xref></p></section>

Output: <section><p>These pages are all about XSLT, an XML-based language <xref ref-type="bibr" rid="r1 r2 r3">1--3</xref> for translating one set of XML into another set of XML, <xref ref-type="bibr" rid="r3 r5 r6 r7">3, 5--7</xref> or into HTML. Of course, there are all sorts of other pages <xref ref-type="bibr" rid="r7 r8">7, 8</xref> around that cover XSLT. <xref ref-type="bibr" rid="r12 r15 r16 r17 r18 r19 r20">12, 15--20</xref></p></section>

仅当字符(,)逗号空格或()空格或( - )两个连字符或空的外部参照元素(<xref ref-type="bibr" rid="r2"/>)出现在外部参照元素之间时,才会发生合并。

E.g.
Input content: <xref ref-type="bibr" rid="r3">3</xref>, <xref ref-type="bibr" rid="r5">5</xref><xref ref-type="bibr" rid="r6"/>--<xref ref-type="bibr" rid="r7">7</xref>  

Expected ouput: <xref ref-type="bibr" rid="r1 r2 r3">1--3</xref>

谢谢和问候 巴拉

1 个答案:

答案 0 :(得分:1)

使用XSLT 2.0,您可以使用for-each-group select="node()" group-adjacent="boolean(self::xref | self::text()[matches(., $pattern)]查找相邻节点,以便使用

等方法
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="xs" version="2.0">

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

    <xsl:template match="*[xref]">
        <xsl:copy>
            <xsl:apply-templates select="@*"/>
            <xsl:for-each-group select="node()"
                group-adjacent="boolean(self::xref | self::text()[matches(., '^[\s\p{P}]+$')])">
                <xsl:choose>
                    <xsl:when test="current-grouping-key()">
                        <xsl:copy>
                            <xsl:copy-of select="@* except @rid"/>
                            <xsl:attribute name="rid" select="current-group()/@rid"/>
                            <xsl:value-of select="current-group()"/>
                        </xsl:copy>
                    </xsl:when>
                    <xsl:otherwise>
                        <xsl:apply-templates select="current-group()"/>
                    </xsl:otherwise>
                </xsl:choose>
            </xsl:for-each-group>
        </xsl:copy>
    </xsl:template>

</xsl:stylesheet>