我有以下XML,我正在尝试生成HTML文件。
<?xml version="1.0" encoding="UTF-8"?>
<text>
<body>
<milestone unit="fragment"/>
<div>
<p>First line text in FIRST fragment</p>
<p>Second line <seg>text in FIRST</seg> fragment</p>
<p>Third line text in FIRST fragment</p>
<milestone unit="fragment"/>
<p>First line text in SECOND fragment</p>
<p>Second line <seg>text in SECOND </seg> fragment</p>
<p>Third line text in SECOND fragment</p>
<milestone unit="fragment"/>
<p>First line text in THIRD fragment</p>
<p>Second line <seg>text in THIRD </seg> fragment</p>
<p>Third line text in THIRD fragment</p>
</div>
</body>
</text>
预期的HTML输出:
HTML 1:
<p>First line text in FIRST fragment</p>
<p>Second line <span>text in FIRST</span>fragment</p>
<p>Third line text in FIRST fragment</p>
HTML 2:
<p>First line text in SECOND fragment</p>
<p>Second line <span>text in SECOND </span> fragment</p>
<p>Third line text in SECOND fragment</p>
HTML 3:
<p>First line text in THIRD fragment</p>
<p>Second line <span>text in THIRD </span> fragment</p>
<p>Third line text in THIRD fragment</p>
这是我用于每个组的XSLT,用于在“里程碑”标记之间对节点进行分组,但是分组不会按预期发生。
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="xs" version="2.0">
<xsl:output method="html" name="html" encoding="UTF-8" indent="yes" omit-xml-declaration="yes" include-content-type="no"/>
<xsl:template match="/">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="body">
<xsl:for-each-group select="descendant::*" group-starting-with="milestone[@unit='fragment']">
<xsl:variable name="currFragNumber">
<xsl:number count="milestone[@unit='fragment']" level="any" from="text"/>
</xsl:variable>
<xsl:result-document href="{$currFragNumber}.html" format="html">
<xsl:apply-templates select="current-group()" />
</xsl:result-document>
</xsl:for-each-group>
</xsl:template>
<xsl:template match="p">
<p>
<xsl:apply-templates/>
</p>
</xsl:template>
<xsl:template match="seg">
<span>
<xsl:apply-templates/>
</span>
</xsl:template>
</xsl:stylesheet>
以下是转换后的输出。
HTML 1:
<p>First line text in FIRST fragment</p>
<p>Second line <span>text in FIRST</span>fragment</p>
<p>Third line text in FIRST fragment</p>
<p>First line text in SECOND fragment</p>
<p>Second line <span>text in SECOND</span>fragment</p>
<p>Third line text in SECOND fragment</p>
<p>First line text in THIRD fragment</p>
<p>Second line <span>text in THIRD</span>fragment</p>
<p>Third line text in THIRD fragment</p>
<p>First line text in FIRST fragment</p>
<p>Second line <span>text in FIRST</span>fragment</p>
<span>text in FIRST</span>
<p>Third line text in FIRST fragment</p>
HTML 2:
<p>First line text in SECOND fragment</p>
<p>Second line <span>text in SECOND </span> fragment</p>
<span>text in SECOND </span>
<p>Third line text in SECOND fragment</p>
HTML 3:
<p>First line text in THIRD fragment</p>
<p>Second line <span>text in THIRD </span> fragment</p>
<span>text in THIRD </span>
<p>Third line text in THIRD fragment</p>
我试图理解为什么第一个当前组()(即第一个“里程碑”)与整个文档匹配,而不仅仅是“里程碑”标记之间的节点。
答案 0 :(得分:1)
问题是你正在选择div
,正如我在评论中所建议的那样。
使用:
<xsl:for-each-group select="div/*"
group-starting-with="milestone[@unit='fragment']">
它将正确序列化三个结果文档。请注意,您可能会忘记第一个milestone
,因为根据http://www.w3.org/TR/xslt20/#xsl-for-each-group
如果是
group-starting-with
属性 存在,那么它的价值必须是a 图案。在这种情况下,项目在 人口必须都是节点。人口中的节点是 检查人口秩序。如果一个 节点匹配模式,或是 人口中的第一个节点 * ,然后是a 创建新组和节点 成为它的第一个成员。除此以外, 节点分配给同一组 作为其前面的节点 人口。
*:重点是我的。
答案 1 :(得分:0)
修改:在我最初的回复(下方)中,我认为select
属性的值必须是一个模式,现在我发现我被规范误导了。
在这种情况下,报告的行为很可能是一个错误。
@Jahangir,祝贺发现了至少三个XSLT 2.0处理器的错误。
W3C XSLT 2.0规范(关于select
的{{1}}属性):
“•如果是group-starting-with属性 存在,那么它的价值必须是a 模式“。
模式规则只允许在模式中使用xsl:for-each-group
或child::
轴。
因此,attribute::
不允许作为模式。我想XSLT处理器将其视为“可恢复的错误”并将其自身的操作视为恢复。
解决方案是将第一个descendant::*
元素放在milestone
的紧随其后的兄弟的适当位置,并更改div
xsl:for-each-group {{1 }} DIV / *`:
select attribute of
和
to: