当前位置:  开发笔记 > 编程语言 > 正文

使用lxml(在python中)处理XHTML文档时,为什么xpath不起作用?

如何解决《使用lxml(在python中)处理XHTML文档时,为什么xpath不起作用?》经验,为你挑选了2个好方法。

我正在测试以下测试文档:




   
        hi there
    
    
        
    

如果我使用lxml.html解析文档,我可以使用xpath获取IMG:

>>> root = lxml.html.fromstring(doc)
>>> root.xpath("//img")
[]

但是,如果我将文档解析为XML并尝试获取IMG标记,则会得到一个空结果:

>>> tree = etree.parse(StringIO(doc))
>>> tree.getroot().xpath("//img")
[]

我可以直接导航到元素:

>>> tree.getroot().getchildren()[1].getchildren()[0]

但是,这当然不能帮助我处理任意文件.我也希望能够查询etree来获得一个直接识别这个元素的xpath表达式,从技术上讲,我可以这样做:

>>> tree.getpath(tree.getroot().getchildren()[1].getchildren()[0])
'/*/*[2]/*'
>>> tree.getroot().xpath('/*/*[2]/*')
[]

但是,该xpath显然对解析任意文档没有用.

显然我在这里遗漏了一些关键问题,但我不知道它是什么.我最好的猜测是它与命名空间有关,但是唯一定义的命名空间是默认的,我不知道在命名空间方面我还需要考虑什么.

那么,我错过了什么?



1> Ned Batcheld..:

问题是名称空间.当作为XML解析,img标签是在http://www.w3.org/1999/xhtml命名空间,因为这是该元素的默认命名空间.你要求没有命名空间的img标签.

试试这个:

>>> tree.getroot().xpath(
...     "//xhtml:img", 
...     namespaces={'xhtml':'http://www.w3.org/1999/xhtml'}
...     )
[]



2> Dimitre Nova..:

XPath认为所有未加前缀的名称都在"无名称空间"中.

特别是规范说:

"使用表达式上下文中的命名空间声明将节点测试中的QName扩展为扩展名.这与开始和结束标记中的元素类型名称的扩展相同,除了使用xmlns声明的默认命名空间是未使用:如果QName没有前缀,则名称空间URI为null(这与扩展属性名称的方式相同)."

请参阅这两个问题的详细解释及其解决方案:此处此处.解决方案是将前缀(与正在使用的API)相关联,并使用它来为XPath表达式中任何未加前缀的名称添加前缀.

希望这有帮助.

干杯,

Dimitre Novatchev

推荐阅读
喜生-Da
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有