XSLT - 对相同内容进行两次分组
XSLT -Grouping twice the same content
我有一个这样的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) 按 para
属性对 <p>
进行分组,并向每个 <p>
组添加单独的部分。
2) 识别 <p>
节点组,其中 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>
但我无法 运行 将这两个代码组合在一起并获得所需的输出。
谁能建议我如何组合以上两个代码并获得预期的输出?
您实际上需要将代码嵌套在第一个模板的 xsl:for-each-group
中的第二个模板中,因此您可以 <xsl:for-each-group select="current-group()" ... />
.[=14= 而不是 <xsl:apply-tempates 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>
我有一个这样的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) 按 para
属性对 <p>
进行分组,并向每个 <p>
组添加单独的部分。
2) 识别 <p>
节点组,其中 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>
但我无法 运行 将这两个代码组合在一起并获得所需的输出。
谁能建议我如何组合以上两个代码并获得预期的输出?
您实际上需要将代码嵌套在第一个模板的 xsl:for-each-group
中的第二个模板中,因此您可以 <xsl:for-each-group select="current-group()" ... />
.[=14= 而不是 <xsl:apply-tempates 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>