我想使用逐项列表而不是硬中断,请参阅示例:
<para>line1<?linebreak?>
line2<?linebreak?>
line3</para>
但是,我在递归模板中遇到奇怪的行为,导致无法正确处理第二行。我已经创建了简化的测试用例 - 不再是递归的了。如果以这种方式使用count(preceding::processing-instruction('linebreak')) = 0
表达式,则不返回任何内容,但我希望第二行。
<line>line1</line><node>
line2<?linebreak?>
line3</node>
line2
此<node>
元素用于调试目的。它确认我处理了预期的数据。
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:template match="para[processing-instruction('linebreak')]">
<xsl:call-template name="getLine">
<xsl:with-param name="node" select="./node()"/>
</xsl:call-template>
</xsl:template>
<xsl:template name="getLine">
<xsl:param name="node"/>
<line>
<xsl:copy-of
select="$node/self::processing-instruction('linebreak')[not(preceding::processing-instruction('linebreak'))]/preceding::node()"
/>
</line>
<xsl:call-template name="getSecondLine">
<xsl:with-param name="node"
select="$node/self::processing-instruction('linebreak')[not(preceding::processing-instruction('linebreak'))]/following::node()"
/>
</xsl:call-template>
</xsl:template>
<xsl:template name="getSecondLine">
<xsl:param name="node"/>
<node>
<xsl:copy-of select="$node"/>
</node>
<xsl:copy-of
select="$node/self::processing-instruction('linebreak')[count(preceding::processing-instruction('linebreak')) = 0]/preceding::node()"
/>
</xsl:template>
</xsl:stylesheet>
在Saxon HE / EE 9.6.0.7中测试(在Oxygen XML Editor 18中)。
答案 0 :(得分:2)
第一个换行符的处理工作正常:
<line>
<xsl:copy-of
select="$node/self::processing-instruction('linebreak')
[not(preceding::processing-instruction('linebreak'))]
/preceding::node()"/>
</line>
虽然只在这个样本上;对于更复杂的数据,您会得到错误的结果,因为您应该使用preceding-sibling
轴而不是preceding
轴。
但代码可以大大简化,我会将select
表达式写为:
select="$node[self::processing-instruction('linebreak')][1]
/preceding-sibling::node()"
第二次换行的处理似乎很困惑。您正在传递参数
$node/self::processing-instruction('linebreak')
[not(preceding::processing-instruction('linebreak'))]
/following::node()"
实际上是
select="$node[self::processing-instruction('linebreak')][1]
/following-sibling::node()"
选择三个节点
line2<?linebreak?>line3
(加上空白),您在<node>
元素中输出,生成
<node>line2<?linebreak?>line3</node>
(再次忽略空白)
然后你做
select="$node/self::processing-instruction('linebreak')
[count(preceding::processing-instruction('linebreak'))=0]
/preceding::node()"
这里$node/self::processing-instruction('linebreak')
选择这三个节点中的第二个节点,这是第二个换行处理指令。前面(或前面的兄弟)处理指令的计数是1,因为你正在处理的指令是第二个。
我不太清楚你在想什么,但我怀疑你的错误是将“前面”和“跟随”视为相对于$node
序列中节点位置的选择,而不是相对于原始源树中的其他节点。我建议阅读描述各种轴的XPath参考书的部分。