为何//Operator无法找到XML节点,而//*[name()='Operator']可行?
问题原因与解决方案
这不是bug,是XML命名空间导致的XPath查询问题,具体原因和解决方法如下:
核心原因
你处理的XML文档中,Operator节点属于某个特定的XML命名空间(可通过xml_ns(xml)查看完整命名空间定义)。xml2基于的libxml2在执行XPath查询时,默认会严格区分命名空间:
- 直接使用
//Operator查询时,XPath会匹配没有任何命名空间的<Operator>节点; - 但实际文档中的
<Operator>节点是带有命名空间前缀的,因此查询返回空节点集。
而xml_find_chr(xml, 'name(*/*/*/*/*/*)')能识别到节点名,是因为name()函数仅返回节点的本地名称,忽略了命名空间信息;//*[name() = "Operator"]本质是通过本地名称匹配,绕开了命名空间的限制,所以能查到目标节点。
正确解决方案
方法1:显式指定命名空间查询
- 先获取文档的命名空间:
ns <- xml_ns(xml)
- 在XPath中使用命名空间前缀查询:
xml_find_all(xml, "//siri:Operator", ns)
(注:siri是命名空间前缀,实际需以xml_ns(xml)返回的前缀为准)
方法2:忽略命名空间的通用查询(不推荐)
如果你不需要区分命名空间,也可以使用更严谨的本地名称匹配方式(避免多命名空间同名节点误匹配):
xml_find_all(xml, '//*[local-name() = "Operator"]')
内容的提问来源于stack exchange,提问作者MichaelChirico
相关产品推荐
相关产品推荐

