Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Xml + copier un noeud dans un autre fichier sans importNode

30 views
Skip to first unread message

Julien Vitard

unread,
Jun 20, 2006, 11:42:19 AM6/20/06
to
Bonjour,

Je suis sous Python 2.4, et je souhaite dupliquer un noeud et
ce qu'il contient dans ce fichier XML :

> fichier example.xml

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<example>
<!-- A PARTIR D'ICI -->
<g id="g9" transform="translate(-927.8893,-263.0905)">
<path d="AB" id="path10" />
</g>
<g id="g13" transform="translate(-927.8893,-263.0905)">
<path d="AB" id="path14" />
</g>
<g id="g15" transform="translate(-927.8893,-263.0905)">
<path d="AB" id="path16" />
</g>
<!-- JUSQUE LA -->
</example>

Je voudrais récupérer les balises <g ...> </g> avec tout les attributs,
etc... pour l'incorporer dans un autre fichier XML à un endroit précis :

> fichier target.xml

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<target>
<g id="g1312" transform="translate(-927.8893,-263.0905)">
<path d="Mz" id="path1314" />
</g>
<g id="g1316" transform="translate(-927.8893,-263.0905)">
<path d="Mz" id="path1318" />
</g>
<g id="g1320" transform="translate(-927.8893,-263.0905)">
<path d="Mz" id="path1322" />
</g>
<!-- A METTRE ICI -->
</target>


Cela fonctionne avec importNode mais j'aimerais me compliquer la vie
en n'utilisant pas importNode !

voilà mon bout de code en utilisant importNode :

#!/usr/bin/env python

import xml.dom.minidom
import sys

test = open('test01.xml','w')

equation = xml.dom.minidom.parse("example.xml")
g_equation = equation.getElementsByTagName('g')

target = xml.dom.minidom.parse("example.xml")
root = target.documentElement

for item in g_equation:
x = target.importNode(item,True)
target.childNodes[0].appendChild(x)

test.write(str(root.toxml()))

test.close()


Si vous avez des idées, je suis preneur!
Merci

Julien

jmdes...@gmail.com

unread,
Jun 20, 2006, 4:41:55 PM6/20/06
to

Je ne sais pas exactement ce que vous désirez faire d'autre (que
copier un noeud) qui requiert absolument minidom mais peut-être que
ça vaudrait le coup de considérer elementTree de Fredrik Lundh.
Pour le moment c'est une librairie "externe" (third-party) mais il fera
partie de la prochaine version de python (2.5)
La raison de cette suggestion est qu'il fonctionne tellement plus
simplement que n'importe quoi que j'ai vu à date sur le traitement
d'XML : simple, facile (une heure d'apprentissage max ;-)), élégant
et rapide.
Je n'ai pas le temps de vous montrer votre code en exemple (désolé,
j'.ai une course ) mnais si vous êtes intéressé, je pourrais le
faire ce soir (heure de montréal, il est actuellement 16hre). Entout
cas, c'est une idée...

Jean-Marc

Laurent Pointal

unread,
Jun 21, 2006, 3:02:20 AM6/21/06
to
Julien Vitard a écrit :

J'ai fait un système de recopie de contenu pour du HTML, en faisant du
"brut": identification des offsets du début et de la fin de l'élément
dans le flot de données, et après simplement une manipulation de chaînes.
Dans mon cas j'ai utilisé le HTMLParser, il faudrais voir s'il y a moyen
de récupérer l'offset de l'élément en cours de traitement dans le flot
en entrée via les API SAX / DOM (ou via elementstree).

A+

Laurent.

jmdes...@gmail.com

unread,
Jun 21, 2006, 9:51:04 AM6/21/06
to

Désolé pour le retard ;-)
(grosse soirée hier!)

Voici la version proposée:
#############################################
import elementtree.ElementTree as ET

masource = ET.ElementTree(file="source.xml")
madestination = ET.ElementTree(file="destination.xml")

mesmembres=racinesource.findall("g")
# mesmembres=racinesource.getiterator("g") #voir NOTE plus bas

""" On trouve le noeud cible auquel ajouter les enfants"""
racinedestination=madestination.getroot()

for i in mesmembres:
racinedestination.append(i)

madestination.write("destination.xml",encoding="UTF-8")
#############################################
NOTE1: j'ai testé avec tes fichiers que j'ai cependant renommés
'source.xml' et 'destination.xml'

NOTE2: findall trouve les sous-éléments directs,
getiterator trouve tous les sous-éléments recursivement

Naturellement, on aurait pu procéder autrement (SIC) mais j'ai gardé
l'exemple proche du tien.
Par ailleurs avec insert() on peut ajouter un noeud à un index
spécifique etc etc. Beaucoup de plaisir en perspective et très
pythonesque.

Jean-Marc

Julien Vitard

unread,
Jun 22, 2006, 2:42:41 AM6/22/06
to
Bonjour,

Merci pour le bout de code, il fonctionne (en remplaçant racinesource
par masource). Mais, et je vais être lourd, je préférerais continuer à
utiliser minidom ou dom, mais sans cette satanée fonction importNode.

> Voici la version proposée:
> #############################################
> import elementtree.ElementTree as ET
>
> masource = ET.ElementTree(file="source.xml")
> madestination = ET.ElementTree(file="destination.xml")
>
> mesmembres=racinesource.findall("g")
> # mesmembres=racinesource.getiterator("g") #voir NOTE plus bas
>
> """ On trouve le noeud cible auquel ajouter les enfants"""
> racinedestination=madestination.getroot()
>
> for i in mesmembres:
> racinedestination.append(i)
>
> madestination.write("destination.xml",encoding="UTF-8")
> #############################################
> NOTE1: j'ai testé avec tes fichiers que j'ai cependant renommés
> 'source.xml' et 'destination.xml'
>

Mais ElementTree me parait assez simple à mettre en oeuvre, pour des
utilisations futures et pythonesques. Pour l'instant mon code doit
fonctionner sans avoir à installer de modules tiers. Mais je garde
l'exemple, Merci.

Julien

julienvitard

unread,
Jun 23, 2006, 4:46:51 PM6/23/06
to
Bonsoir,

J'ai un début de code qui fonctionne mais pas jusqu'au bout ;-(
le voici :

import xml.dom.minidom
import sys

equation = xml.dom.minidom.parse("example.xml")
g_equation = equation.getElementsByTagName('g')
target = xml.dom.minidom.parse("example.xml")

example_Node = target.firstChild

for g_Node in example_Node.childNodes:
if g_Node.nodeType == 1:
# Node 'g'
a = g_Node.attributes["id"]
# print a.name + " = " + a.value
b = g_Node.attributes["transform"]
# print b.name + " = " + b.value
new = target.createElement("g")
new.setAttribute(a.name,a.value)
new.setAttribute(b.name,b.value)

for path_Node in g_Node.childNodes:
if path_Node.nodeType == 1:
# Node 'path'
# print path_Node.toxml()
c = path_Node.attributes["d"]
# print c.name + " = " + c.value
d = path_Node.attributes["id"]
# print d.name + " = " + d.value
new_child = target.createElement("path")
new_child.setAttribute(c.name,c.value)
new_child.setAttribute(d.name,d.value)
new.appendChild(new_child)
print new.toxml()
## target.documentElement.appendChild(new)

test = open('test.xml','w')
test.write(str(target.toxml()))
test.close()

toujours sur mes deux fichiers de départ, j'arrive à récupérer
les noeuds, les attributs mais je n'arrive pas (ligne commentée
avec ##) à créer le noeud dans target !

N.B.: le nodeType == 1 c'est pour Element, le fichier example.xml
contient des noeuds Text (nodeType == 3)

Si vous avez des idées pour terminer ce bout de code je suis preneur
et si vous avez plus rapide, plus pythonesque, mais sans importNode,
ni utiliser de module autre que Dom ou minidom.

Merci

Julien

0 new messages