Python lxml E-Factory
我一直在使用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 个回答
解释一下:在 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)。
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>'