在这个xpath中:
/A/B[C='hello']
C="hello"
是C[text()='hello']
的某种句法快捷方式吗?是否记录在哪里?
编辑:好的,我发现了一个区别:C=
返回C和C的子节点中的所有文本节点,而C[text()=
只返回文本节点在C.
现在,假设我有XML:
<root>
<A>
<B>
<C>hello<E>EEE</E>world</C>
<D>world</D>
</B>
<B>
<C>goodbye</C>
<D>mars</D>
</B>
</A>
</root>
如何使用语法C[text()=
选择包含第一个C节点的B节点?我可以使用C=
语法获取B节点,如下所示:
/root/A/B[C="helloEEEworld"]
但这不起作用:
/root/A/B[C[text()="helloworld"]]
也不这样做:
/root/A/B[C[text()="hello world"]]
/root/A/B[C[text()="helloEEEworld"]]
嗯......这很有效:
/root/A/B[C[text()="hello"]]
为什么? text()
仅返回第一个文本节点吗?根据W3C,text()
返回上下文节点的所有文本节点子节点。
答案 0 :(得分:2)
text()
确实将所有文本节点子项作为节点列表
当您使用/root/A/B[C[text()="hello"]]
时,您指的是获取B
个C
个孩子的节点任何直接子节点等于"hello"
。
以同样的方式匹配:
/root/A/B[C[text()="world"]]
或明确指定您希望通过完全的第一个或第二个直接子文本节点获取节点:
/root/A/B[C[text()[1]="hello"]]
/root/A/B[C[text()[2]="world"]]
如果您希望将所需节点与其完整文本内容进行匹配,则可以使用
/root/A/B[C[.="helloEEEworld"]]
或
/root/A/B[C="helloEEEworld"]
答案 1 :(得分:1)
C
中的 [C='hello']
将返回上下文元素的直接子元素C
的所有B
元素。所以整个谓词是一个布尔表达式,包含节点集和字符串之间的 比较 (注意元素是XPath data model中的一种节点),此案例的行为记录在规范中如下:
如果要比较的一个对象是节点集而另一个是字符串,那么当且仅当节点集中有一个节点使得执行比较的结果时,比较才为真。节点的字符串值和另一个字符串为true。如果要比较的一个对象是节点集而另一个是布尔值,那么当且仅当对布尔值和将节点集转换为布尔值的结果执行比较的结果时,比较才为真。使用布尔函数是真的。 [source]
C='hello'
中的{p> /A/B[C='hello']
将被评估为true
,如果转换为字符串后的任何C
元素等于'hello'。因此,如果您愿意,它更像是C[string()='hello']
的捷径。
“嗯......这很有效:
/root/A/B[C[text()="hello"]]
为什么? text()只返回第一个文本节点吗?根据W3C,text()返回上下文节点的所有文本节点子节点。“
此上下文中的text()
不是第一个文本节点,而是返回所有直接子文本节点。这是因为child::
是XPath中的默认轴。将XPath与其等效的详细版本进行对比:
/child::root/child::A/child::B[child::C[child::text()="hello"]]