我正在尝试使用xsl:for-each在XSLT 2.0中对元素进行分组。
以下是我输入的说明:
<root>
<chapter>
<heading> heading text </heading>
<title> title </title>
<p> 1111 </p>
<p> 2222 </p>
<center> text </center>
<p> 3333 </p>
<title> another title </title>
<p> 4444 </p>
<center> text </center>
<p> 5555 </p>
</chapter>
<chapter>
<heading> heading text </heading>
<title> another title </title>
<p> 6666 </p>
<p> 7777 </p>
<title> another title </title>
<p> 8888 </p>
<p> 9999 </p>
</chapter>
<root>
我正在尝试通过匹配每个<title>
元素并将每个后续元素分组,直到下一个<title>
成为元素<section>
来对此文档进行分组。这就是我希望输出看起来像:
<root>
<chapter>
<heading> Heading text </heading>
<section>
<title> title </title>
<p> 1111 </p>
<p> 2222 </p>
<center> text </center>
<p> 3333 </p>
</section>
<section>
<title> title </title>
<p> 4444 </p>
<center> text </center>
<p> 5555 </p>
</section>
<section>
<title> title </title>
<p> 6666 </p>
<p> 7777 </p>
<center> text </center>
<p> 8888 </p>
<p> 9999 </p>
</section>
<chapter>
<root>
我当前的模板无效:
<xsl:template match="chapter">
<chapter>
<xsl:for-each-group select="*" group-starting-with="title">
<section>
<xsl:copy-of select="current-group()" />
</section>
</xsl:for-each-group>
</chapter>
</xsl:template>
上面的样式表会对我想要的部分进行分组,但是出于某种原因,它还会将每个<heading>
元素分组到自己的<section>
中。有什么建议吗?
提前致谢。
答案 0 :(得分:4)
我会用......
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes" />
<xsl:strip-space elements="*" />
<xsl:template match="/*">
<root>
<xsl:for-each-group select="chapter" group-by="heading">
<chapter>
<xsl:copy-of select="current-group()[1]/heading" />
<xsl:for-each-group select="current-group()/(* except heading)"
group-starting-with="title">
<section>
<xsl:copy-of select="current-group()" />
</section>
</xsl:for-each-group>
</chapter>
</xsl:for-each-group>
</root>
</xsl:template>
</xsl:stylesheet>
答案 1 :(得分:4)
我通常使用xsl:在for-each-group的主体中选择,以区分真正以group-starting-with元素开头的组和第一个“真实组”之前的“leading rump”。如果你知道“领先的臀部”只包含一个标题元素,那么你已经获得了许多其他解决方案。另一个更通用的解决方案(因为它不会对臀部中的内容做出任何假设),但是沿着相同的路线,是:
<xsl:copy-of select="title[1]/preceding-sibling::*">
<xsl:for-each-group select="title[1]/(., following-sibling::*)">
<section>
<xsl:copy-of select="current-group()"/>
</section>
</xsl:for-each-group>
答案 2 :(得分:3)
你可能想要
<xsl:copy-of select="current-group()" />
而不是value-of
。对于标题,如果您知道每章只有一个heading
元素,那么您可以说
<xsl:template match="chapter">
<xsl:copy-of select="heading" />
<xsl:for-each-group select="*[not(self::heading)]" group-starting-with="title">
<section>
<xsl:copy-of select="current-group()" />
</section>
</xsl:for-each-group>
</xsl:template>
即。单独拉出标题,然后将其从要分组的元素集中排除。