XSLT - 分析给定节点的后续兄弟节点
XSLT - analyze following sibling of a given node
我有一个 xml 如下,
<doc>
<h1>header 1</h1>
<p>para</p>
<p>para</p>
<h1>header 2</h1>
<p>para</p>
<h2>header 2 sub h1</h2>
<h2>header 2 sub h2</h2>
<h1>header 3</h1>
<p>para</p>
<p>para</p>
<h1>header 4</h1>
<h2>header 4 sub h1</h2>
<p>para</p>
</doc>
我需要的是有序获取所有 <h1>
和 <h2>
节点并创建一个无序列表,
所以最终输出应该是这样的,
<doc>
<ul>
<li><h1>header 1</h1><li>
<li><h1>header 2</h1></li>
<ul>
<li><h2>header 2 sub h1</h2></li>
<li><h2>header 2 sub h2</h2><li>
</ul>
<li><h1>header 3</h1></li>
<li><h1>header 4 sub h1</h1></li>
<ul>
<li><h2>zz</h2></li>
</ul>
</ul>
</doc>
我写的xsl如下,
<xsl:template match="doc">
<doc>
<xsl:for-each select="//h1">
<li>
<xsl:apply-templates/>
</li>
<ul>
<xsl:for-each-group select="//h2" group-by="count(preceding::h1)">
<li><xsl:apply-templates/></li>
</xsl:for-each-group>
</ul>
</xsl:for-each>
</doc>
</xsl:template>
给出的结果如下,
<doc>
<li>header 1</li>
<ul><li>header 2 sub h1header 4 sub h1</li></ul>
<li>header 2</li>
<ul></li>header 2 sub h1header 4 sub h1</li></ul>
<li>header 3</li>
<ul></li>header 2 sub h1header 4 sub h1</li></ul>
<li>header 4</li>
<ul></li>header 2 sub h1header 4 sub h1</li></ul>
</doc>
如您所见,我已经使用 for-each 摸索在相关 <h1>
节点下添加 <h2>
节点。 (这是我能想到的在其相关 <h1>
节点下添加 <h2>
节点的解决方案。)但是如您所见,它没有给出预期的输出。
你能建议我如何更改我的代码以获得预期结果的方法吗?或者可能是另一种获得预期结果的方法?
为此,您需要分组开始。
<xsl:template match="doc">
<ul>
<xsl:for-each-group select="*" group-starting-with="h1">
<li><xsl:copy-of select="."/></li>
<ul>
<xsl:apply-templates select="current-group()[self::h2]"/>
</ul>
</xsl:for-each-group>
</ul>
</xsl:template>
你真的想要这个输出吗?在 HTML 中,<ul>
元素的所有子元素都必须是 <li>
元素。但是,就 XSLT 而言,您应该能够采用这种方法。
我有一个 xml 如下,
<doc>
<h1>header 1</h1>
<p>para</p>
<p>para</p>
<h1>header 2</h1>
<p>para</p>
<h2>header 2 sub h1</h2>
<h2>header 2 sub h2</h2>
<h1>header 3</h1>
<p>para</p>
<p>para</p>
<h1>header 4</h1>
<h2>header 4 sub h1</h2>
<p>para</p>
</doc>
我需要的是有序获取所有 <h1>
和 <h2>
节点并创建一个无序列表,
所以最终输出应该是这样的,
<doc>
<ul>
<li><h1>header 1</h1><li>
<li><h1>header 2</h1></li>
<ul>
<li><h2>header 2 sub h1</h2></li>
<li><h2>header 2 sub h2</h2><li>
</ul>
<li><h1>header 3</h1></li>
<li><h1>header 4 sub h1</h1></li>
<ul>
<li><h2>zz</h2></li>
</ul>
</ul>
</doc>
我写的xsl如下,
<xsl:template match="doc">
<doc>
<xsl:for-each select="//h1">
<li>
<xsl:apply-templates/>
</li>
<ul>
<xsl:for-each-group select="//h2" group-by="count(preceding::h1)">
<li><xsl:apply-templates/></li>
</xsl:for-each-group>
</ul>
</xsl:for-each>
</doc>
</xsl:template>
给出的结果如下,
<doc>
<li>header 1</li>
<ul><li>header 2 sub h1header 4 sub h1</li></ul>
<li>header 2</li>
<ul></li>header 2 sub h1header 4 sub h1</li></ul>
<li>header 3</li>
<ul></li>header 2 sub h1header 4 sub h1</li></ul>
<li>header 4</li>
<ul></li>header 2 sub h1header 4 sub h1</li></ul>
</doc>
如您所见,我已经使用 for-each 摸索在相关 <h1>
节点下添加 <h2>
节点。 (这是我能想到的在其相关 <h1>
节点下添加 <h2>
节点的解决方案。)但是如您所见,它没有给出预期的输出。
你能建议我如何更改我的代码以获得预期结果的方法吗?或者可能是另一种获得预期结果的方法?
为此,您需要分组开始。
<xsl:template match="doc">
<ul>
<xsl:for-each-group select="*" group-starting-with="h1">
<li><xsl:copy-of select="."/></li>
<ul>
<xsl:apply-templates select="current-group()[self::h2]"/>
</ul>
</xsl:for-each-group>
</ul>
</xsl:template>
你真的想要这个输出吗?在 HTML 中,<ul>
元素的所有子元素都必须是 <li>
元素。但是,就 XSLT 而言,您应该能够采用这种方法。