【问题标题】:XML pretty print fails in Python lxmlPython lxml中的XML漂亮打印失败
【发布时间】:2018-05-27 05:50:52
【问题描述】:

我正在尝试在 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。

我也尝试将换行符添加为btail,但随后连缩进都被破坏了。

编辑:我需要 c 元素在开始和结束标记中保持分隔:&lt;c&gt;&lt;/c&gt;。这就是我在示例中使用method='HTML' 的原因。

【问题讨论】:

  • 删除method='html'或使用method='xml'
  • 谢谢,这为我指明了正确的解决方案!

标签: xml python-2.7 lxml pretty-print


【解决方案1】:

在编写时使用“xml”输出方法(这是默认的,因此不必明确给出)。

c 元素的text 属性设置为空字符串,以确保该元素被序列化为&lt;c&gt;&lt;/c&gt;

代码:

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>

【讨论】:

    【解决方案2】:

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

    不优雅,但工作。

    【讨论】:

    • 您可以将c 元素的text 属性设置为空字符串,而不是对文档进行两次解析。这将确保元素被序列化为&lt;c&gt;&lt;/c&gt;。见stackoverflow.com/a/19548368/407651
    • 太棒了!空字符串和什么都没有之间的区别。你愿意把你的 cmets 变成一个答案吗?我宁愿接受你的,也不愿接受我的。
    猜你喜欢
    • 2011-07-02
    • 2012-03-25
    • 2017-12-19
    • 1970-01-01
    • 2013-11-08
    • 2018-10-04
    相关资源
    最近更新 更多