【问题标题】:Appending an xml-node which is read from file breaks pretty_print for adjacent nodes附加从文件中读取的 xml 节点会破坏相邻节点的 pretty_print
【发布时间】:2016-11-25 10:28:53
【问题描述】:

我正在使用 python 的 etree 库生成一个 XML 文件。生成文件中的一个节点是从现有 XML 文件中读取的。添加此元素会破坏之前和之后节点的 pretty_print。

import xml.etree.cElementTree as ET
from lxml import etree

root = etree.Element("startNode")
subnode1 = etree.SubElement(root, "SubNode1")
subnode1Child1 = etree.SubElement(subnode1, "subNode1Child1")
etree.SubElement(subnode1Child1, "Child1")
etree.SubElement(subnode1Child1, "Child2")

f = open('/xml_testdata/ext_file.xml','r')
ext_xml = etree.fromstring(f.read())
ext_subnode = ext_xml.find("ExtNode")
subnode1.append(ext_subnode)

subnode1Child2 = etree.SubElement(subnode1, "subNode1Child2")
etree.SubElement(subnode1Child2, "Child1")
etree.SubElement(subnode1Child2, "Child2")

tree = etree.ElementTree(root)
tree.write("testfile.xml", xml_declaration=True, pretty_print=True)

给出这个结果:

<startNode>
    <SubNode1><subNode1Child1><Child1/><Child2/></subNode1Child1><ExtNode>
            <NodeFromExt>
                <SubNodeFromExt1/>
            </NodeFromExt>
            <NodeFromExt>
                <SubNodeFromExt2/>
                <AnotherSubNodeFromExt2>
                    <SubSubNode/>
                    <AllPrettyHere>
                        <Child/>
                    </AllPrettyHere>
                </AnotherSubNodeFromExt2>
            </NodeFromExt>
    </ExtNode>
    <subNode1Child2><Child1/><Child2/></subNode1Child2></SubNode1>
</startNode>

不是很可读,是吗?当“subNodeChild”包含比这个例子更多的子节点时更糟糕!

没有附加外部元素,它看起来像这样:

<startNode>
  <SubNode1>
    <subNode1Child1>
      <Child1/>
      <Child2/>
    </subNode1Child1>
    <subNode1Child2>
      <Child1/>
      <Child2/>
    </subNode1Child2>
  </SubNode1>
</startNode>

所以问题是由附加外部元素引起的!

有没有办法在不破坏漂亮打印输出的情况下附加外部元素?

【问题讨论】:

    标签: python xml append elementtree pretty-print


    【解决方案1】:

    您可以使用解析器对象在解析现有 XML 文件时删除可忽略的空格,从而获得更漂亮的打印输出。

    而不是这个:

    f = open('/xml_testdata/ext_file.xml','r')
    ext_xml = etree.fromstring(f.read())
    

    使用这个:

    f = open('/xml_testdata/ext_file.xml', 'r')
    parser = etree.XMLParser(remove_blank_text=True)
    ext_xml = etree.fromstring(f.read(), parser)
    

    另见:

    【讨论】:

    • 顺便说一下,可以用etree.parse('/xml_testdata/ext_file.xml', parser)代替etree.fromstring(f.read(), parser)
    【解决方案2】:

    通过使用 etree.SubElement 创建“ExtNode”并在其中添加元素,我已经能够在一定程度上减轻这种影响:

    ext_node = etree.SubElement(subnode1, "ExtNode")
    for element in ext_xml.findall("ExtNode/NodeFromExt")
      ext_node.append(element)
    

    有这个结果:

    <startNode>
      <SubNode1>
        <subNode1Child1>
          <Child1/>
          <Child2/>
        </subNode1Child1>
        <ExtNode><NodeFromExt>
          <SubNodeFromExt1/>
            </NodeFromExt>
        <NodeFromExt>
          <SubNodeFromExt2/>
            <AnotherSubNodeFromExt2>
              <SubSubNode/>
              <AllPrettyHere>
                <Child/>
              </AllPrettyHere>
            </AnotherSubNodeFromExt2>
        </NodeFromExt>
      </ExtNode>
        <subNode1Child2>
          <Child1/>
          <Child2/>
        </subNode1Child2>
      </SubNode1>
    </startNode>
    

    不完美,但至少是人类可读的(这就是 pretty_print 的全部意义,对吧?)

    为了满足我的强迫症,如果有办法获得格式完美的文件,我仍然很感兴趣!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-11-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多