lxml xpath 的语法问题

2 投票
1 回答
557 浏览
提问于 2025-04-18 12:03

我在用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)

撰写回答