从XML表示的树中创建子树 - python

0 投票
1 回答
3249 浏览
提问于 2025-04-15 20:14

我有一个XML文件,它的结构像一棵树,我需要从中创建一个子树。

比如说:

<a>
  <b>
    <c>Hello</c>
  <d>
    <e>Hi</e>
</a>

这个子树会是

<root>
<a>
  <b>
    <c>Hello</c>
   </b>
</a>
<a>
  <d>
     <e>Hi</e>
  </d>
</a>
</root>

在Python中,有哪个最好的XML库可以做到这一点?如果有现成的算法也能帮上忙就更好了。注意:这个XML文档不会很大,可以轻松放进内存里。

1 个回答

4

ElementTree 这个工具在“读取”和“写入”XML时都很好用,而且很简单。

你给的第一个XML示例(我编辑了你的问题,只是为了让它更易读!)是无效的,我猜是因为缺少了bd的结束标签。你所说的“子树”看起来根本不像子树,更像是你第一个格式的重写。

除了“美化”问题(比如添加换行和缩进让结果XML看起来更好看;-),如果我理解得没错,这段代码应该能满足你的要求:

try:
  import xml.etree.cElementTree as et
  import cStringIO as sio
except ImportError:
  import xml.etree.ElementTree as et
  import StringIO as sio

xmlin = sio.StringIO('''<a>
  <b>
    <c>Hello</c>
  </b>
  <d>
    <e>Hi</e>
  </d>
</a>
''')

tin = et.parse(xmlin)
top = tin.getroot()
tou = et.ElementTree(et.Element('root'))
newtop = tou.getroot()
for child in top.getchildren():
  subtree = et.Element(top.tag)
  subtree.append(child)
  newtop.append(subtree)

import sys
tou.write(sys.stdout)

开头的try/except部分尝试在“正常”的平台上使用C版本的模块,如果不可用就退回到纯Python的模块(比如App Engine、Jython、IronPython等)。

然后我构建了两个树——tin是输入树,来自你给的XML字符串;tou是输出树,最开始除了根元素外是空的。

接下来的部分是一个非常简单的循环,遍历tin的根节点下的所有子元素:对于每一个子元素,构建一个合适的子树并添加到tou的根节点下的子元素中——就是这么简单。

最后两行展示了生成的树(虽然因为空格问题看起来不太好,但在XML结构上是完全正确的;-)。

撰写回答