Python lxml

时间:2017-12-13 10:58:01

标签: xml python-2.7 lxml pretty-print

我正在尝试使用Python 2.7.6中的lxml 4.1.1读取,修改和编写XML文件。

我的代码:

import lxml.etree as et

fn_xml_in = 'in.xml'
parser = et.XMLParser(remove_blank_text=True)
xml_doc = et.parse(fn_xml_in, parser)
xml_doc.getroot().find('b').append(et.Element('c'))
xml_doc.write('out.xml', method='html', pretty_print=True)

输入文件in.xml如下所示:

<a>
    <b/>
</a>

生成的输出文件out.xml

<a>
    <b><c></c></b>
</a>

或者当我设置remove_blank_text=True时:

<a><b><c></c></b></a>

我原本期望lxml在b元素中插入换行符和缩进词:

<a>
    <b>
        <c></c>
    </b>
</a>

我怎样才能做到这一点?

我尝试了一些tidy lib包装器,但它们似乎专注于HTML而不是XML。

我还尝试将换行符添加为b&#39; tail,但即使缩进也被破坏了。

修改:我需要c元素在开始和结束标记中保持分开:<c></c>。这就是我在示例中使用method='HTML'的原因。

2 个答案:

答案 0 :(得分:3)

写入时使用“xml”输出方法(这是默认值,因此不必明确指定)。

text元素的c属性设置为空字符串,以确保元素序列化为<c></c>

代码:

import lxml.etree as et

parser = et.XMLParser(remove_blank_text=True)
xml_doc = et.parse('in.xml', parser)

b = xml_doc.getroot().find('b')
c = et.Element('c')
c.text=''
b.append(c)

xml_doc.write('out.xml', pretty_print=True)

结果(out.xml):

<a>
  <b>
    <c></c>
  </b>
</a>

答案 1 :(得分:0)

感谢mzjn的评论,我找到了一个有效但不优雅的解决方案。由于我需要在HTML语法中保留空元素,因此仅使用method='XML'并不令人满意。

将文档格式化两次会产生所需的结果:

import lxml.etree as et

parser = et.XMLParser(remove_blank_text=True)
xml_doc = et.parse('in.xml', parser)
xml_doc.getroot().find('b').append(et.Element('c'))
xml_doc.write('out.xml', pretty_print=True)

parser = et.XMLParser(remove_blank_text=False)
xml_doc = et.parse('out.xml', parser)
xml_doc.write('out.xml', pretty_print=True, method='HTML')

结果:

<a>
  <b>
    <c></c>
  </b>
</a>

不优雅,但工作。