使用 XSLT 1.0 包装两个标记出现之间的所有内容
Wrap everything between two tag occurrences with XSLT 1.0
我想通过顶级 h1
标签将 XML(实际上是 XHTML)文档分成几部分。从 <h1>
的第一个开始到下一个的所有内容都应该包含在 <section>
元素中,依此类推,直到文档结束。
例如,如果我有这个源文件:
<article>
<h1>Heading 1</h1>
<p>Some text</p>
<p>Some more text</p>
<h1>Heading 2</h1>
<p>Some text</p>
<h2>Subheading</h2>
<p>Some text</p>
<h1 id="heading3">Heading 3</h1>
<p>Some text</p>
</article>
我希望结果完全像这样:
<article>
<section>
<h1>Heading 1</h1>
<p>Some text</p>
<p>Some more text</p>
</section>
<section>
<h1>Heading 2</h1>
<p>Some text</p>
<h2>Subheading</h2>
<p>Some text</p>
</section>
<section>
<h1 id="heading3">Heading 3</h1>
<p>Some text</p>
</section>
</article>
问题是我只有 libxslt1.1(因此,XSLT 1.0 + EXSLT)。使用 XSLT 2.0,我可以用漂亮的 <xsl:for-each-group select="*" group-starting-with="h1">
做一些事情,但遗憾的是,这对我来说不是一个可行的选择。
我不想根据属性值进行分组(我没有任何有意义的属性),因此,据我所知,Muenchian 分组不是对我有用的技巧。不过,也许我错了 - 我几分钟前才读到这个方法。
有什么方法可以用 XSLT 1.0 实现这个吗?
as I understand it, Muenchian grouping is not a trick that would work
for me.
嗯,非常接近它的东西会:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:key name="grpById" match="*[not(self::h1)]" use="generate-id(preceding-sibling::h1[1])" />
<xsl:template match="/article">
<xsl:copy>
<xsl:for-each select="h1">
<section>
<xsl:copy-of select=". | key('grpById', generate-id())"/>
</section>
</xsl:for-each>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
使用键 name="group" match="article/*[not(self::h1)]" use="count(preceding-sibling::h1)"
,然后在匹配 article
的模板中将模板应用于 h1
子元素,并在 h1
的模板中创建部分并复制.|key('group', position())
.
我想通过顶级 h1
标签将 XML(实际上是 XHTML)文档分成几部分。从 <h1>
的第一个开始到下一个的所有内容都应该包含在 <section>
元素中,依此类推,直到文档结束。
例如,如果我有这个源文件:
<article>
<h1>Heading 1</h1>
<p>Some text</p>
<p>Some more text</p>
<h1>Heading 2</h1>
<p>Some text</p>
<h2>Subheading</h2>
<p>Some text</p>
<h1 id="heading3">Heading 3</h1>
<p>Some text</p>
</article>
我希望结果完全像这样:
<article>
<section>
<h1>Heading 1</h1>
<p>Some text</p>
<p>Some more text</p>
</section>
<section>
<h1>Heading 2</h1>
<p>Some text</p>
<h2>Subheading</h2>
<p>Some text</p>
</section>
<section>
<h1 id="heading3">Heading 3</h1>
<p>Some text</p>
</section>
</article>
问题是我只有 libxslt1.1(因此,XSLT 1.0 + EXSLT)。使用 XSLT 2.0,我可以用漂亮的 <xsl:for-each-group select="*" group-starting-with="h1">
做一些事情,但遗憾的是,这对我来说不是一个可行的选择。
我不想根据属性值进行分组(我没有任何有意义的属性),因此,据我所知,Muenchian 分组不是对我有用的技巧。不过,也许我错了 - 我几分钟前才读到这个方法。
有什么方法可以用 XSLT 1.0 实现这个吗?
as I understand it, Muenchian grouping is not a trick that would work for me.
嗯,非常接近它的东西会:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:key name="grpById" match="*[not(self::h1)]" use="generate-id(preceding-sibling::h1[1])" />
<xsl:template match="/article">
<xsl:copy>
<xsl:for-each select="h1">
<section>
<xsl:copy-of select=". | key('grpById', generate-id())"/>
</section>
</xsl:for-each>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
使用键 name="group" match="article/*[not(self::h1)]" use="count(preceding-sibling::h1)"
,然后在匹配 article
的模板中将模板应用于 h1
子元素,并在 h1
的模板中创建部分并复制.|key('group', position())
.