Python lxml E-Factory

5 投票
2 回答
3686 浏览
提问于 2025-04-17 05:55

我一直在使用lxml的"E-Factory"(也叫ElementMaker)来创建xml文档。我想生成一个类似这样的xml文档:

<url>
  <date-added>2011-11-11</date-added>
</url>

但是,使用E-factory时,我不太确定如何在'data-added'元素中指定连字符(-)。它似乎把连字符当成了负号来处理。

这是我参考的文档: http://lxml.de/tutorial.html#the-e-factory

下面是如何重现这个错误的方法:

from lxml import etree
from lxml.builder import ElementMaker 

E = ElementMaker()
URL = E.url
DATE_ADDED = E.date-added

xml = URL(DATE_ADDED(myobject.created.strftime('%Y-%m-%dT%H:%M:%S')),)


NameError global name 'added' is not defined

有没有人知道有什么技巧可以让它正确渲染带有连字符的元素?

谢谢你的阅读。

2 个回答

9

解释一下:在 E. 后面你写的东西需要是一个 有效的 Python 标识符。这包括下划线,但不包括连字符。E.date-added 被编译时看起来“成功”,就像 (E.date) - added 一样,但在运行时会失败,因为在你的例子中 added 并没有被定义。

替代方案:

(1) E.tag 只是一个表面上的技巧,并不是所有合法的 XML 标签都能用。实际上,Python 对象的属性可以是任何东西,只是你不能在源代码中写 obj.really+funky%attribute*name,dude。一个不太好的技巧需要一个更好的替代方案:你可以保持元素创建的相同模式,也就是说在每次创建元素时不需要每次都指定标签,可以这样做:

DATE_ADDED = getattr(E, 'date-added')

然后像现在一样使用 DATE_ADDED

(2) 如果你能控制架构,建议使用下划线(date_added)而不是连字符(date-added)。

7

ElementMaker 是一个工具,它可以把一个函数和一个标签名(比如 E.date_added)联系起来,用来构建 XML 树。不过,HTML/XML 标签和 Python 函数允许的字符是有区别的。根据 PEP 8 的规定:"包和模块的名称应该简短,并且全部使用小写字母。如果在模块名称中使用下划线能提高可读性,也是可以的"。所以,date_added 这个函数里有个下划线,而在 Python 函数中是不允许的:

>>> def foo-bar():
  File "<stdin>", line 1
    def foo-bar():
           ^
SyntaxError: invalid syntax

为了解决这个问题,可以稍微详细一点地创建 date-added 标签,直接把名字作为参数传进去:

>>> etree.tostring(E.url(E('date-added', '2011-11-11')))
'<url><date-added>2011-11-11</date-added></url>'

撰写回答