面对这个:
<div>
some text
<!-- this is the hook comment-->
target part 1
target part 2
<!-- this is another comment-->
some other text
</div>
我正在尝试达到以下期望的输出:
目标部分1 目标部分2
注释和文本元素的数量未知,但是目标文本始终位于包含hook
的注释之后。因此,该想法是找到相关position()
中的comment()
,并获取下一个元素。
以前有一些关于finding the position of an element containing a certain text或by attribute的问题,但是comment()
是一个奇怪的鸭子,我无法修改这种情况的答案。例如,尝试对答案进行修改:
//comment()[contains(string(),'hook')]/preceding::*
或使用preceding-sibling::*
,什么也不返回。
所以我决定尝试其他方法。 xml中的count(//node())
返回6
。并且//node()[2]
返回相关的comment()
。但是,当我尝试使用index-of()
(应该返回2
)来获得该评论的位置时
index-of(//node(),//comment()[contains(string(),'hook')])
它返回3
!
当然,我可以忽略它,而使用3
索引位置作为目标文本的位置(而不是将2
递增1),但是我想知道,首先,为什么结果是什么,其次,它会带来任何意想不到的后果。
答案 0 :(得分:1)
如果要获取两个注释之间的节点,则无需首先找到元素的position()
(FYI position()
取决于所选的整个节点集)。
您可以直接获取元素-这里是text()
节点。像这样的示例文件
<?xml version="1.0" encoding="UTF-8"?>
<root>
<div>
some text
<!-- this is the hook comment-->
target part 1
target part 2
<!-- this is another comment-->
some other text
<!-- this is another comment-->
no one needs this
<!-- this is another comment-->
this is also useless
<!-- this is another hook comment-->
second target text
<!-- this is another comment-->
again some useless crap
<!-- this is another comment-->
and the last piece that noone needs
</div>
</root>
可以用以下表达式查询
//comment()[contains(string(),'hook')]/following-sibling::text()[preceding-sibling::comment()[1][contains(string(),'hook')]]
产生
target part 1
target part 2
second target text
如果只需要第一个块,则将表达式限制为第一项:
(//comment()[contains(string(),'hook')]/following-sibling::text()[preceding-sibling::comment()[1][contains(string(),'hook')]])[1]
其结果是
target part 1
target part 2
根据需要。
如果可以使用XPath-2.0,则可以在上面的表达式后附加/position()
,以获取comment()
的位置。但是,如上所述,它们相对于评论节点。因此结果将是1 2
。