ElementTree est bon et simple à la fois pour "lire" et "écrire". Votre premier exemple XML (j'ai édité votre question juste pour ajouter la mise en forme afin qu'elle soit lisible!) Est invalide, je présume des balises de fermeture manquantes pour b
et d
comme apparaître dans ce que vous appelez "la sous-arborescence" (qui ressemble rien de tel qu'un sous-arbre pour moi, mais on dirait que c'est comme une réécriture de votre première forme).
net des questions « prettyfication » (par exemple en ajoutant des sauts de ligne et des indentations pour rendre le XML résultant soit jolie ;-), ce code devrait faire ce que vous demandez, si je vous comprends bien:
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)
L'essai/excepté au début essaye d'utiliser les versions C des modules sur des plates-formes "normales" où elles sont disponibles, retomber dans les modules purs-Python (pour App Engine, Jython, IronPython, ...).
Ensuite, je construis deux arbres - tin
, l'entrée, à partir de la chaîne XML que vous avez donné; tou
, la sortie 1, initialement vide à l'exception de l'élément racine.
Tout le reste est une boucle très simple sur tous les sous-éléments de tin
« s racine: pour chacun, un sous-arbre approprié est construit et ajouté aux sous-éléments de tou
» root s - c'est tout ce qu'il ya à faire.
Les deux dernières lignes montrent l'arbre résultant (pas joli, en raison de problèmes d'espaces, mais parfaitement correct en termes de structure XML ;-).