XSLT - 将相同内容分组两次

时间:2015-09-22 08:12:00

标签: xml xslt xslt-2.0

我有一个像这样的xml,

<doc>
    <section>
        <p id="main">aa</p>
        <p id="main">bb</p>
        <p id="main">cc</p>
        <p id="para1">dd</p>
        <p id="st_main">ee</p>
        <p id="st_main">ff</p>
        <p id="main">cc</p>
        <p id="main">cc</p>
        <p id="main">gg</p>
        <p id="para2">hh</p>
        <p id="main">ii</p>
        <p id="st_main">jj</p>
        <p id="st_main">cc</p>
        <p id="main">cc</p>
        <p id="para1">xx</p>
        <p id="main">yy</p>
        <p id="st_main">zz</p>
        <p id="main">cc</p>
    </section>
</doc>

我的要求是

1)按<p>属性对para进行分组,并为每个<p>群组添加单独的部分。

2)确定<p>个{I}}属性从id开始st <st_start><st_end>属于该组的开始和结束

所以预期的输出是,

<doc>
    <section>
        <p id="main">aa</p>
        <p id="main">bb</p>
        <p id="main">cc</p>
    </section>
    <section type="para1">
        <p id="para1">dd</p>
        <ss_start/>
        <p id="st_main">ee</p>
        <p id="st_main">ff</p>
        <ss_end/>
        <p id="main">cc</p>
        <p id="main">cc</p>
        <p id="main">gg</p>
    </section>
    <section type="para2">
        <p id="para2">hh</p>
        <p id="main">ii</p>
        <ss_start/>
        <p id="st_main">jj</p>
        <p id="st_main">cc</p>
        <ss_end/>
        <p id="main">cc</p>
    </section>
    <section type="para1">
        <p id="para1">xx</p>
        <p id="main">yy</p>
        <ss_start/>
        <p id="st_main">zz</p>
        <ss_end/>
        <p id="main">cc</p>
    </section>
</doc>

我可以使用以下xsl

分别执行此任务
<xsl:template match="section">
        <xsl:for-each-group select="p" group-starting-with="p[starts-with(@id, 'para')]">
            <section>
                <xsl:if test="current-group()[1][not(@id='main')]">
                    <xsl:attribute name="type" select="current-group()[1]/@id"/>
                </xsl:if>
                <xsl:apply-templates select="current-group()"/>
            </section>
        </xsl:for-each-group>
    </xsl:template>


<xsl:template match="section">
        <xsl:copy>
            <xsl:for-each-group select="*" group-adjacent="starts-with(@id, 'st')">
                <xsl:if test="current-grouping-key()">
                    <ss_start/>
                </xsl:if>
                <xsl:apply-templates select="current-group()"/>
                <xsl:if test="current-grouping-key()">
                    <ss_end/>
                </xsl:if>
            </xsl:for-each-group>
        </xsl:copy>
    </xsl:template>

但是我无法将这两个代码一起运行并获得所需的输出。

任何人都可以建议我如何合并以上两个代码并获得预期的输出?

1 个答案:

答案 0 :(得分:1)

您实际上需要将代码嵌套在第一个模板的xsl:for-each-group内的第二个模板中,因此您不必执行<xsl:apply-tempates select="current-group()" /> <xsl:for-each-group select="current-group()" ... />

试试这个单一模板:

<xsl:template match="section">
    <xsl:for-each-group select="p" group-starting-with="p[starts-with(@id, 'para')]">
        <section>
            <xsl:if test="current-group()[1][not(@id='main')]">
                <xsl:attribute name="type" select="current-group()[1]/@id"/>
            </xsl:if>
            <xsl:for-each-group select="current-group()" group-adjacent="starts-with(@id, 'st')">
                <xsl:if test="current-grouping-key()">
                    <ss_start/>
                </xsl:if>
                <xsl:apply-templates select="current-group()"/>
                <xsl:if test="current-grouping-key()">
                    <ss_end/>
                </xsl:if>
            </xsl:for-each-group>
        </section>
    </xsl:for-each-group>
</xsl:template>