ElementTree хорош и прост как для "чтения", так и для "письма".
Ваш первый пример XML (я отредактировал ваш вопрос только для того, чтобы добавить форматирование, чтобы оно было читабельным!) Недействителен, я предполагаю, что отсутствуют закрывающие теги для b
и d
, которые появляются в том, что вы называете "поддерево" (для меня это не похоже на поддерево, но похоже, что оно предназначено для переписывания вашей первой формы).
За исключением проблем с «симпатичным отображением» (например, добавление новых строк и отступов для придания получающемуся 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)
Попытка / исключение в начале пытается использовать версии модулей C на «обычных» платформах, где они доступны, в противном случае используйте чисто Python-модули (для App Engine, Jython, IronPython, .. .).
Затем я строю два дерева - tin
, входное, из заданной вами строки XML; tou
, выходной, изначально пустой, за исключением корневого элемента.
Все остальное - очень простой цикл для всех подэлементов корня tin
: для каждого подходящее поддерево создается и добавляется к подэлементам корня tou
- это все, что нужно сделать .
Последние две строки показывают результирующее дерево (не красиво, из-за проблем с пробелами, но совершенно правильно с точки зрения структуры XML; -).