lxml xpath 的语法问题
我在用Python的lxml库解析XML时,遇到了如何正确写语法来获取单个元素的问题,搞得我很困惑。
当我这样做的时候:
print self.root.xpath("descendant::*[@Name='GevCCP']/*",namespaces=self.nsmap)
我得到了一个子节点的列表:
[<Element {http://www.genicam.org/GenApi/Version_1_0}ToolTip at 0x1175830>, <Element {http://www.genicam.org/GenApi/Version_1_0}Description at 0x117b6c8>, <Element {http://www.genicam.org/GenApi/Version_1_0}DisplayName at 0x117bb48>, <Element {http://www.genicam.org/GenApi/Version_1_0}Visibility at 0x117bb90>, <Element {http://www.genicam.org/GenApi/Version_1_0}Streamable at 0x117bd88>, <Element {http://www.genicam.org/GenApi/Version_1_0}EnumEntry at 0x117b8c0>, <Element {http://www.genicam.org/GenApi/Version_1_0}EnumEntry at 0x1214878>, <Element {http://www.genicam.org/GenApi/Version_1_0}EnumEntry at 0x1214560>, <Element {http://www.genicam.org/GenApi/Version_1_0}pValue at 0x1214a70>]
那么我该怎么直接用xpath语法访问这个列表的第一个子元素呢?
我试过:
print self.root.xpath("descendant::*[@Name='GevCCP']/ToolTip",namespaces=self.nsmap)
结果却是一个空的集合:
[]
我还尝试在xpath中指定命名空间,但这总是导致出现一个错误:lxml.etree.XPathEvalError: Invalid expression
。
最终,我想对各种元素都这样做,比如:
self.root.xpath("descendant::*[@Name='GevCCP']/pValue")
self.root.xpath("descendant::*[@Name='GevCCP']/EnumEntry[@Name='Group']/Value")
self.root.xpath("descendant::*[@Name='GevHeartbeatTimeoutReg']/Address")
但是lxml的文档似乎没有涵盖我的使用场景,而我找到的关于xpath和命名空间的其他资料也不够完整。
1 个回答
3
最好的解决办法是注册一个在你的XML源文件中使用的命名空间。通常,这个过程是通过给它分配一个前缀来实现的,这样你就可以在表达式中使用这个前缀。你的nsmap
变量是否正确地映射了这些命名空间呢?选择一个前缀,比如说g
:
self.nsmap = {'g': 'http://www.genicam.org/GenApi/Version_1_0'}
然后使用这个前缀来指定你的XPath选择器:
self.root.xpath("descendant::*[@Name='GevCCP']/g:ToolTip", namespaces=self.nsmap)