Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Xml + copier un noeud dans un autre fichier sans importNode

5 réponses
Avatar
Julien Vitard
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

5 réponses

Avatar
jmdeschamps
Julien Vitard wrote:
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 attribut s,
etc... pour l'incorporer dans un autre fichier XML à un endroit préci s :

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


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


Avatar
Laurent Pointal
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!


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.


Avatar
jmdeschamps
Julien Vitard wrote:
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 attribut s,
etc... pour l'incorporer dans un autre fichier XML à un endroit préci s :

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


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


Avatar
Julien Vitard
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

Avatar
julienvitard
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