在 XSLT 1.0 中,论坛中的一个常见问题是如何将平面 HTML 转换为分层 XML,这很多时候归结为在<br />
标签中的<p>
标签之间嵌套文本。
我有一个类似的问题,我认为我已经使用 XSLT 2.0 部分解决了这个问题,但这对我来说是一种新方法,我想获得第二个意见。
XHTML 源代码<span class="pageStart"></span>
分散在各处。它们可以出现在几个不同的父节点中。我想将一个页面开始标记和下一个页面之间的所有节点包装在一个<page>
节点中。我目前的解决方案是:
<xsl:template match="*[child::span[@class='pageStart']]">
<xsl:copy>
<xsl:copy-of select="@*" />
<xsl:for-each-group select="node()"
group-starting-with="span[@class='pageStart']">
<page>
<xsl:apply-templates select="current-group()"/>
</page>
</xsl:for-each-group>
</xsl:copy>
</xsl:template>
这至少有一个缺陷——标记的父节点<page>
在我不想要它时将它作为子节点。在其他作品中,如果在其中<div>
任何地方都有一个子页面标记,则除了我期望的位置之外,还会<page>
创建一个节点作为直接子节点。<div>
我曾希望我可以简单地使模板规则成为<xsl:template match="span[@class='pageStart']">
,但无论我尝试什么, current-group() 似乎都是空的。我尝试的常识方法是<xsl:for-each-group select="node()" group-starting-with="span[@class='pageStart']">
.
有没有更简单的方法来解决我缺少的这个问题?
编辑
这是输入的示例:
<?xml version="1.0" encoding="UTF-8"?>
<html>
<head></head>
<body>
<span class="pageStart"/>
<p>...</p>
<div>...</div>
<img />
<p></p>
<span class="pageStart"/>
<div>...</div>
<span class="pageStart"/>
<p>...</p>
<div>
<span class="pageStart"/>
<p>...</p>
<p>...</p>
<span class="pageStart"/>
<div>...</div>
<img/>
</div>
</body>
</html>
我假设最后两个嵌套页面使这个问题变得更加困难,所以我很高兴将它作为输出,或者接近的东西:
<?xml version="1.0" encoding="UTF-8"?>
<html>
<head></head>
<body>
<page>
<span class="pageStart"/>
<p>...</p>
<div>...</div>
<img />
<p></p>
</page>
<page>
<span class="pageStart"/>
<div>...</div>
</page>
<page>
<span class="pageStart"/>
<p>...</p>
<div>
<page>
<span class="pageStart"/>
<p>...</p>
<p>...</p>
</page>
<page>
<span class="pageStart"/>
<div>...</div>
<img/>
</page>
</div>
</page>
</body>
</html>