如何将 lxml xpath 函数导入默认命名空间?

kev*_*kev 3 python xpath lxml

这是lxml 文档中的一个示例:

>>> regexpNS = "http://exslt.org/regular-expressions"
>>> find = etree.XPath("//*[re:test(., '^abc$', 'i')]",
...                    namespaces={'re':regexpNS})

>>> root = etree.XML("<root><a>aB</a><b>aBc</b></root>")
>>> print(find(root)[0].text)
aBc
Run Code Online (Sandbox Code Playgroud)

我想将re:test()函数导入默认命名空间,这样我就可以在没有前缀的情况下调用它re:。我该怎么做?谢谢!

mat*_*ata 5

您可以将一个函数放在空函数命名空间中:

functionNS = etree.FunctionNamespace(None)
functionNS['test'] = lambda context, nodes, *args: print(context, nodes, args)
Run Code Online (Sandbox Code Playgroud)

通过这样做,新test函数已经使用空命名空间前缀注册,这意味着您可以像这样使用它:

root.xpath("//*[test(., 'arg1', 'arg2')]")
Run Code Online (Sandbox Code Playgroud)

不幸的是,python 无法提供调用的函数"{http://exslt.org/regular-expressions}test",只能在 C 中实现的 lxml 扩展中使用,因此您不能简单地将它分配给functionNS['test'].

这意味着您需要在 python 中重新实现它以将其分配给空函数命名空间...

如果这不值得为您省去输入三个字符的麻烦,您可以使用这个技巧来使re命名空间的前缀成为全局的:

etree.FunctionNamespace("http://exslt.org/regular-expressions").prefix = 're'
Run Code Online (Sandbox Code Playgroud)

那么至少你不需要为每个 xpath 表达式传递命名空间字典。