首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >计数以前的节点返回意外的结果。

计数以前的节点返回意外的结果。
EN

Stack Overflow用户
提问于 2016-12-07 12:32:22
回答 1查看 54关注 0票数 0

我想使用逐项列表,而不是硬中断,参见下面的示例:

代码语言:javascript
复制
<para>line1<?linebreak?>
line2<?linebreak?>
line3</para>

但是,我在递归模板中遇到了奇怪的行为,这妨碍了正确处理第二行。我已经创建了简化的测试用例--不再是递归的。如果以这种方式使用count(preceding::processing-instruction('linebreak')) = 0表达式,则不会返回任何内容,但我希望看到第二行。

代码语言:javascript
复制
<line>line1</line><node>
line2<?linebreak?>
line3</node>
line2

<node>元素在这里用于调试。它证实了我处理预期的数据。

代码语言:javascript
复制
<?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 (在氧气XML编辑器18)。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-12-07 17:35:32

第一个换行器的处理工作正常:

代码语言:javascript
复制
<line>
   <xsl:copy-of
     select="$node/self::processing-instruction('linebreak')
              [not(preceding::processing-instruction('linebreak'))]
              /preceding::node()"/>
</line>

尽管只对此示例;对于更复杂的数据,您将得到错误的结果,因为您应该使用的是preceding-sibling轴而不是preceding轴。

但是代码可以大大简化,我会将select表达式编写为:

代码语言:javascript
复制
select="$node[self::processing-instruction('linebreak')][1]
        /preceding-sibling::node()"

第二行的处理似乎非常混乱。您正在传递参数

代码语言:javascript
复制
$node/self::processing-instruction('linebreak')
   [not(preceding::processing-instruction('linebreak'))]
   /following::node()"

这是有效的

代码语言:javascript
复制
select="$node[self::processing-instruction('linebreak')][1]
            /following-sibling::node()"

选择三个节点

代码语言:javascript
复制
line2<?linebreak?>line3

(加上空格),在<node>元素中输出,生成

代码语言:javascript
复制
<node>line2<?linebreak?>line3</node>

(再次忽略空格)

然后你就知道了

代码语言:javascript
复制
select="$node/self::processing-instruction('linebreak')
  [count(preceding::processing-instruction('linebreak'))=0]
  /preceding::node()"

这里,$node/self::processing-instruction('linebreak')选择这三个节点中的第二个,这是第二个换行处理指令。前面(或前面的兄弟姐妹)处理指令的计数为1,因为您正在处理的是第二个指令。

我不太清楚您在想什么,但我怀疑您的错误是将“前面”和“跟随”看作相对于$node序列中节点的位置,而不是相对于原始源树中的其他节点。我建议阅读XPath参考书中描述各种轴的部分。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/41017579

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档