我有一个xml如下,
<doc>
<h1>header 1</h1>
<p>para 1</p>
<p>para 2</p>
<h1>header 2</h1>
<p>para 3</p>
<p>para 4</p>
<h1>header 3</h1>
<p>para 5</p>
<p>para 6</p>
</doc>
我的要求是从<h1>
创建无序列表,并将这些列表项链接到<p>
个节点之后。
所以期望的输出应该是,
<doc>
<div name="list">
<ul>
<li><a href="h1-1">header 1</a></li>
<li><a href="h1-2">header 2</a></li>
<li><a href="h1-3">header 3</a></li>
</ul>
</div>
<div class="content">
<div id="h1-1">
<p>para 1</p>
<p>para 2</p>
</div>
<div id="h1-2">
<p>para 3</p>
<p>para 4</p>
</div>
<div id="h1-3">
<p>para 5</p>
<p>para 6</p>
</div>
</div>
</doc>
我写了以下xsl来完成这项任务,
<doc>
<div name="list">
<ul>
<xsl:for-each-group select="*" group-starting-with="h1">
<li><a href="h1-{count(preceding::h1)+1}"><xsl:apply-templates/></a></li>
</xsl:for-each-group>
</ul>
</div>
<div class="content">
<xsl:for-each select="h1">
<div id="h1-{count(preceding::h1)+1}">
<!-- should copy follwing <p> nodes in <h1> -->
</div>
</xsl:for-each>
</div>
</doc>
我无法解决的问题是如何将<p>
节点作为以下兄弟节点复制到<h1>
但在显示另一个<h1>
之前。 (例子会给出清晰的想法。)
有人能建议我解决这个问题吗?
答案 0 :(得分:2)
你的方法需要逆转:第一个div
不需要分组,第二个需要分组。
并且没有必要考虑跟随(或之前)兄弟姐妹;只需将组缩小到p
个元素。
XSLT 2.0
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" encoding="UTF-8" indent="yes"/>
<xsl:template match="doc">
<doc>
<div name="list">
<ul>
<xsl:for-each select="h1">
<li>
<a href="h1-{position()}">
<xsl:value-of select="."/>
</a>
</li>
</xsl:for-each>
</ul>
</div>
<div class="content">
<xsl:for-each-group select="*" group-starting-with="h1">
<div id="h1-{position()}">
<xsl:copy-of select="current-group()[self::p]"/>
</div>
</xsl:for-each-group>
</div>
</doc>
</xsl:template>
</xsl:stylesheet>