【问题标题】:How to import lxml xpath functions to default namespace?如何将 lxml xpath 函数导入默认命名空间?
【发布时间】:2013-06-25 08:19:57
【问题描述】:

这是lxml doc中的一个例子:

>>> 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

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

【问题讨论】:

    标签: python xpath lxml


    【解决方案1】:

    你可以把一个函数放在空的函数命名空间中:

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

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

    root.xpath("//*[test(., 'arg1', 'arg2')]")
    

    不幸的是,为"{http://exslt.org/regular-expressions}test" 调用的function 不能从 python 中获得,只能从用 C 实现的 lxml 扩展中获得,因此您不能简单地将其分配给 functionNS['test']

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

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

    etree.FunctionNamespace("http://exslt.org/regular-expressions").prefix = 're'
    

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

    【讨论】:

    • 我对您提出的第二个解决方案感到非常兴奋,但它对我来说破坏了 XPath 的行为。也就是说,如果我用一些正则表达式构造一个 XPath 而没有传递命名空间(因为它是像你提到的那样设置的),那么在第二次评估时它就不起作用。它以某种方式变得混乱,失败并出现错误XPath function '{}match' not found。知道为什么吗?
    • 不知道,无法重现。而且您确定您在任何地方都使用re:match(...),而不是在某处没有前缀的match(...)
    • 我创建了一个 MWE here ... 编辑:MWE 本身不能工作,但它是一个导出的 jupyter 笔记本。当 2 search 在不同的单元格中时,它似乎只在笔记本中失败
    • @CiprianTomoiaga - 嗯,这可能是一个错误,我不确定。在第一次调用已编译的 xpath 表达式后,看起来注册的前缀被遗忘了......不幸的是,我不能说更多。也许你应该为此提出一个新问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-25
    • 2013-06-23
    • 2010-10-07
    • 1970-01-01
    • 2011-12-24
    相关资源
    最近更新 更多