[Python 2.7] Parseur XML et classes : optimisation
Bonsoir, je suis actuellement en train d'essayer de réaliser un parseur XML pour le fichier suivant (qui sera destiné à contenir d'autres entrées) :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| <?xml version="1.0" ?>
<blocks>
<!-- Grass -->
<block id="0">
<basic_proprieties>
<name lang="en" text="Grass" />
<name lang="fr" text="Herbe" />
<image>blocks/grass.png</image>
<cost type="wheels" value="2" />
</basic_proprieties>
</block>
<block id="1">
<basic_proprieties>
<name lang="en" text="Radioactive grass" />
<name lang="fr" text="Herbe radioactive" />
<image>blocks/radioactive_grass.png</image>
<cost type="wheels" value="2" />
</basic_proprieties>
</block>
</blocks> |
Voici le code que j'ai pondu après avoir regadé la doc de minidom :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
| from xml.dom.minidom import parse
from blocks import ModelBlock
def getText(nodelist):
rc = []
for node in nodelist:
if node.nodeType == node.TEXT_NODE:
rc.append(node.data)
return ''.join(rc)
class Parser:
def __init__(self, filepath)
self.document = parse(filepath)
class BlocksParser(Parser):
def __init__(self, filepath):
Parser.__init__(self, filepath)
self.blocks = []
def parse(self):
rootnode = self.document.getElementsByTagName("blocks")[0]
# Basic proprieties
for blocknode in rootnode.getElementsByTagName("block"):
basicpropnode = blocknode.getElementsByTagName("basic_proprieties")[0]
block = ModelBlock()
block.id = int(blocknode.attributes["id"].value)
block.image = getText(basicpropnode.getElementsByTagName("image")[0].childNodes)
# Names
for namenode in basicpropnode.getElementsByTagName("name"):
block.names[namenode.attributes["lang"].value] = namenode.attributes["text"].value
# Costs
for costnode in basicpropnode.getElementsByTagName("cost"):
block.costs[costnode.attributes["type"].value] = costnode.attributes["value"].value
self.blocks.append(block) |
Et pour finir voici la classe ModelBlock :
Code:
1 2 3 4 5 6
| class ModelBlock:
def __init__(self):
self.id = 0
self.names = {}
self.image = ""
self.costs = {} |
Cependant je trouve que ce que j'ai produit n'est pas la meilleure des solutions. En effet j'ai voulu reprendre ce parseur pour un fichier units.xml et j'ai parfois les choses suivante dans le parseur :
Code:
1 2 3 4 5
| unit.id = int(blocknode.attributes["id"].value)
unit.image = getText(basicpropnode.getElementsByTagName("image")[0].childNodes)
unit.health = int(getText(basicpropnode.getElementsByTagName("cost")[0].childNodes))
unit.movingrange = int(getText(basicpropnode.getElementsByTagName("movingrange")[0].childNodes))
unit.movingtype = getText(basicpropnode.getElementsByTagName("movingrange")[0].childNodes) |
Je me demandais donc si il n'y aurait pas une "meilleure" façon de procéder pour accèder aux différents élements des fichiers XML que celle-ci ou j'attribue chaque valeur à un attribut de manière manuelle, en passant par un dictionnaire ? Je n'ai pas trop d'idées.
J'éspère que vous aurez compris mon problème et que vous serez en mesure de m'orienter vers une solution plus "propre" :)
Cordialement,
darkrojo.
EDIT : Je rajoute la classe ModelUnit pour vous donner une idée :
Code:
1 2 3 4 5 6 7 8 9 10 11
| class ModelUnit:
def __init__(self):
self.id = 0
self.names = {}
self.image = ""
self.cost = 0
self.health = 0
self.movingrange = 0
self.movingtype = ""
self.proprieties = {{}} |