我想知道当我使用lxml
以增量方式编写XML时,是否有办法对XML进行简洁的命名空间声明。目前,我通过生成XML的方式获得重复的命名空间。请参阅下文,标记data
和oneEntry
复制命名空间的位置:
<?xml version='1.0' encoding='utf-8'?>
<data xmlns="nsURI1" xmlns:second="nsURI2">
<oneEntry xmlns:second="nsURI2" xmlns="nsURI1">
<subEntry1/>
<second:subEntry2/>
</oneEntry>
</data>
这可以从像这样的脚本生成(受http://lxml.de/api.html#incremental-xml-generation启发)
from lxml import etree
from io import BytesIO
class XmlWriter(object):
ROOT_TAG = 'data'
ENCODING = 'utf-8'
NSMAP = {
None: 'nsURI1',
'second': 'nsURI2'
}
def write(self):
f = BytesIO()
w = self.writer(f) # Creates the writer
next(w) # Start writing (go to first yield)
element = etree.Element('oneEntry', nsmap=self.NSMAP)
etree.SubElement(element, '{nsURI1}subEntry1')
etree.SubElement(element, '{nsURI2}subEntry2')
w.send(element)
w.close() # Closing stream closes root tag
print(f.getvalue().decode('utf-8'))
@classmethod
def writer(cls, out_stream):
with etree.xmlfile(out_stream, encoding=cls.ENCODING) as xf:
xf.write_declaration()
with xf.element(cls.ROOT_TAG, nsmap=cls.NSMAP):
while True:
el = yield
xf.write(el)
xf.flush()
XmlWriter().write()
计算一个条目的部分实际上是一个生成数千个条目的循环,因此我需要一个流。 现在,我理解为什么会这样。计算entry元素的部分不知道我的流编写器中的根标记。因此,在增量写入期间,名称空间在每个条目上都是重复的。这会增加(当我的文件没有压缩时)输出的大小。
我知道如何继续以增量方式编写我的XML,而不必更改它的结构并仍然优先使用lxml
?
非常感谢!