问题描述
给出此XML,
library(xml2)
text = paste0(
'<?xml version="1.0" encoding="UTF-8"?><items>',paste(rep(
'<item type="greeting" id="9273938">
<link type="1" id="139" value="Hi"/>
<link type="1" id="142" value="Hello"/>
</item>',100),collapse = "\n"),'</items>')
x = xml_children(read_xml(text))
我可以使用"link"
或"//link"
选择所有链接节点,并获得相同的结果–但速度却大不相同:
bench::mark(
link = xml_find_all(x,"link"),`//link` = xml_find_all(x,"//link"))[1:5]
# A tibble: 2 x 5
expression min median `itr/sec` mem_alloc
<bch:expr> <bch:tm> <bch:tm> <dbl> <bch:byt>
1 link 1.5ms 1.56ms 606. 10.6KB
2 //link 27.1ms 55.74ms 15.2 558.2KB
为什么会有如此大的差异?
解决方法
因为"link"
仅需要检查当前节点是否具有名为link
的子元素,而"//link"
则必须检查文档中的所有元素以查看哪些元素名为{{1 }}。
XPath注释:
-
link
仅检查当前节点的直接子节点,因为 默认轴为"link"
轴。 -
child::
检查文档中的所有元素,因为"//link"
是//
的快捷方式,因此/descendant-or-self::node()/
是"//link"
的缩写。