Joh*_*ohn 21 python xml xhtml xpath lxml
我正在测试以下测试文档:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>hi there</title>
</head>
<body>
<img class="foo" src="bar.png"/>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)
如果我使用lxml.html解析文档,我可以使用xpath获取IMG:
>>> root = lxml.html.fromstring(doc)
>>> root.xpath("//img")
[<Element img at 1879e30>]
Run Code Online (Sandbox Code Playgroud)
但是,如果我将文档解析为XML并尝试获取IMG标记,则会得到一个空结果:
>>> tree = etree.parse(StringIO(doc))
>>> tree.getroot().xpath("//img")
[]
Run Code Online (Sandbox Code Playgroud)
我可以直接导航到元素:
>>> tree.getroot().getchildren()[1].getchildren()[0]
<Element {http://www.w3.org/1999/xhtml}img at f56810>
Run Code Online (Sandbox Code Playgroud)
但是,这当然不能帮助我处理任意文件.我也希望能够查询etree来获得一个直接识别这个元素的xpath表达式,从技术上讲,我可以这样做:
>>> tree.getpath(tree.getroot().getchildren()[1].getchildren()[0])
'/*/*[2]/*'
>>> tree.getroot().xpath('/*/*[2]/*')
[<Element {http://www.w3.org/1999/xhtml}img at fa1750>]
Run Code Online (Sandbox Code Playgroud)
但是,该xpath显然对解析任意文档没有用.
显然我在这里遗漏了一些关键问题,但我不知道它是什么.我最好的猜测是它与命名空间有关,但是唯一定义的命名空间是默认的,我不知道在命名空间方面我还需要考虑什么.
那么,我错过了什么?
Ned*_*der 27
问题是名称空间.当作为XML解析,img标签是在http://www.w3.org/1999/xhtml命名空间,因为这是该元素的默认命名空间.你要求没有命名空间的img标签.
试试这个:
>>> tree.getroot().xpath(
... "//xhtml:img",
... namespaces={'xhtml':'http://www.w3.org/1999/xhtml'}
... )
[<Element {http://www.w3.org/1999/xhtml}img at 11a29e0>]
Run Code Online (Sandbox Code Playgroud)