Question

J'ai besoin d'utiliser Python 2.4.4 pour convertir du XML à partir d'un dictionnaire Python.Tout ce que je besoin sont les noms des nœuds et des valeurs, je ne suis pas inquiet sur les attributs, car le XML je suis d'analyse n'ont pas.Je ne peux pas utiliser ElementTree car qui n'est pas disponible pour 2.4.4, et je ne peux pas utiliser la 3ème partie des bibliothèques en raison de mon environnement de travail.Quelle est la meilleure façon pour moi de faire cela?Existe-il des bons extraits?

Aussi, si il n'y a pas un moyen facile de faire cela, il y a un autre des formats de sérialisation que Python 2.4.4 a un support natif pour?

Était-ce utile?

La solution

Question Sérialiser Python dictionnaire XML les listes de certains moyens de sérialisation XML.Que d'autres formats de sérialisation, je suppose pickle le module est un outil agréable pour elle.

Autres conseils

J'ai récemment écrit un peu de code pour traduire les données XML en un python structure de données, bien que j'ai eu à gérer des attributs.J'ai utilisé xml.dom.minidom plutôt que de ElementTree, pour une raison similaire.Je n'ai pas réellement testé sur Python 2.4.4, mais je pense que cela fonctionnera.Je n'ai pas écrit un inverse générateur XML, mais vous pouvez probablement utiliser la lispy_string' fonction que j'ai compris pour ce faire.

J'ai aussi inclus quelques raccourcis spécifiques à l'application j'ai écrit (expliqué dans la docstring), mais vous pourriez trouver ces raccourcis utiles, de les sons de celui-ci.Essentiellement, un arbre xml, techniquement, se traduit par un dictionnaire des listes de dictionnaires de listes de dictionnaires de listes, etc.Je omettre la création de l'intermédiaire des listes, sauf s'ils sont nécessaires, de sorte que vous pouvez les éléments de référence par dictname[element1][element2] plutôt que de dictname[element1][0][element2][0] et ainsi de suite.

Attribut de la manipulation est un peu encombrants, je recommande fortement de lire le code avant de faire quoi que ce soit avec des attributs.

import sys
from xml.dom import minidom

def dappend(dictionary, key, item):
    """Append item to dictionary at key.  Only create a list if there is more than one item for the given key.
    dictionary[key]=item if key doesn't exist.
    dictionary[key].append(item) if key exists."""
    if key in dictionary.keys():
        if not isinstance(dictionary[key], list):
            lst=[]
            lst.append(dictionary[key])
            lst.append(item)
            dictionary[key]=lst
        else:
            dictionary[key].append(item)
    else:
        dictionary.setdefault(key, item)

def node_attributes(node):
    """Return an attribute dictionary """
    if node.hasAttributes():
        return dict([(str(attr), str(node.attributes[attr].value)) for attr in node.attributes.keys()])
    else:
        return None

def attr_str(node):
    return "%s-attrs" % str(node.nodeName)

def hasAttributes(node):
    if node.nodeType == node.ELEMENT_NODE:
        if node.hasAttributes():
            return True
    return False

def with_attributes(node, values):
    if hasAttributes(node):
        if isinstance(values, dict):
            dappend(values, '#attributes', node_attributes(node))
            return { str(node.nodeName): values }
        elif isinstance(values, str):
            return { str(node.nodeName): values,
                     attr_str(node): node_attributes(node)}
    else:
        return { str(node.nodeName): values }

def xmldom2dict(node):
    """Given an xml dom node tree,
    return a python dictionary corresponding to the tree structure of the XML.
    This parser does not make lists unless they are needed.  For example:

    '<list><item>1</item><item>2</item></list>' becomes:
    { 'list' : { 'item' : ['1', '2'] } }
    BUT
    '<list><item>1</item></list>' would be:
    { 'list' : { 'item' : '1' } }

    This is a shortcut for a particular problem and probably not a good long-term design.
    """
    if not node.hasChildNodes():
        if node.nodeType == node.TEXT_NODE:
            if node.data.strip() != '':
                return str(node.data.strip())
            else:
                return None
        else:
            return with_attributes(node, None)
    else:
        #recursively create the list of child nodes
        childlist=[xmldom2dict(child) for child in node.childNodes if (xmldom2dict(child) != None and child.nodeType != child.COMMENT_NODE)]
        if len(childlist)==1:
            return with_attributes(node, childlist[0])
        else:
            #if False not in [isinstance(child, dict) for child in childlist]:
            new_dict={}
            for child in childlist:
                if isinstance(child, dict):
                    for k in child:
                        dappend(new_dict, k, child[k])
                elif isinstance(child, str):
                    dappend(new_dict, '#text', child)
                else:
                    print "ERROR"
            return with_attributes(node, new_dict)

def load(fname):
    return xmldom2dict(minidom.parse(fname))

def lispy_string(node, lst=None, level=0):
    if lst==None:
        lst=[]
    if not isinstance(node, dict) and not isinstance(node, list):
        lst.append(' "%s"' % node)
    elif isinstance(node, dict):
        for key in node.keys():
            lst.append("\n%s(%s" % (spaces(level), key))
            lispy_print(node[key], lst, level+2)
            lst.append(")")
    elif isinstance(node, list):
        lst.append(" [")
        for item in node:
            lispy_print(item, lst, level)
        lst.append("]")
    return lst

if __name__=='__main__':
    data = minidom.parse(sys.argv[1])

    d=xmldom2dict(data)

    print d

Dicts en python ne sont pas ordonnées, ne l'oubliez pas.J'ai un code de base, qui est petit et ne nécessite pas de modules externes.La mauvaise, c'est qu'il ne prend pas en charge tout type d'attributs XML, mais vous avez dit

Je ne suis pas inquiet sur les attributs

,si elle est ici:

def d2x(d, root="root"):

    op = lambda tag: '<' + tag + '>'
    cl = lambda tag: '</' + tag + '>\n'
    ml = lambda v,xml: xml + op(key) + str(v) + cl(key)

    xml = op(root) + '\n' if root else ""

    for key,vl in d.iteritems():
        vtype = type(vl)
        if vtype is list: 
            for v in vl:
                xml = ml(v,xml)         
        if vtype is dict: xml = ml('\n' + d2x(vl,None),xml)         
        if vtype is not list and vtype is not dict: xml = ml(vl,xml)

    xml += cl(root) if root else ""

    return xml

Exemple d'utilisation:

mydict = {
"boolean":False,
"integer":12,
"float":3.1,
"listitems":["item1","item2"],
"string":"Hello world", 
"dictionary":{
    "key1":1,
    "key2":2,
    "dictindict":{
                "a":"aaa",
                "b":"bbb"
                }
            }
}
print d2x (mydict,"superxml")

Ce sera d'impression:

<superxml>
<string>Hello world</string>
<dictionary>
<key2>2</key2>
<key1>1</key1>
<dictindict>
<a>aaa</a>
<b>bbb</b>
</dictindict>
</dictionary>
<float>3.1</float>
<listitems>item1</listitems>
<listitems>item2</listitems>
<boolean>False</boolean>
<integer>12</integer>
</superxml>

Pour la sérialisation d'un Python dict pour le format XML, Python suivant la classe fonctionne bien pour moi.Plus d'autres solutions, il a l'avantage qu'il est assez simple et qu'il n'bon encodage XML.Le script est basé sur cette réponse.Il n'a qu'une seule extension:En passant le list_mappings dictionnaire du constructeur, vous pouvez spécifier la manière dont un seul élément de liste (a child à l'intérieur de la children attribut dans l'exemple ci-dessous) est nommé.

from xml.dom.minidom import Document


class DictToXML(object):
    default_list_item_name = "item"

    def __init__(self, structure, list_mappings={}):
        self.doc = Document()

        if len(structure) == 1:
            rootName = str(list(structure.keys())[0])
            self.root = self.doc.createElement(rootName)

            self.list_mappings = list_mappings

            self.doc.appendChild(self.root)
            self.build(self.root, structure[rootName])

    def build(self, father, structure):
        if type(structure) == dict:
            for k in structure:
                tag = self.doc.createElement(k)
                father.appendChild(tag)
                self.build(tag, structure[k])
        elif type(structure) == list:
            tag_name = self.default_list_item_name

            if father.tagName in self.list_mappings:
                tag_name = self.list_mappings[father.tagName]

            for l in structure:
                tag = self.doc.createElement(tag_name)
                self.build(tag, l)
                father.appendChild(tag)
        else:
            data = str(structure)
            tag = self.doc.createTextNode(data)
            father.appendChild(tag)

    def display(self):
        print(self.doc.toprettyxml(indent="  "))

    def get_string(self):
        return self.doc.toprettyxml(indent="  ")


if __name__ == '__main__':
    example = {'sibling': {'couple': {'mother': 'mom', 'father': 'dad', 'children': [{'child': 'foo'},
                                                                                      {'child': 'bar'}]}}}
    xml = DictToXML(example)
    xml.display()

Il donne le résultat suivant:

<?xml version="1.0" ?>
<sibling>
  <couple>
    <children>
      <child>
        <name>foo</name>
      </child>
      <child>
        <name>bar</name>
      </child>
    </children>
    <father>dad</father>
    <mother>mom</mother>
  </couple>
</sibling>

Gris du lien inclut certaines des solutions que l'air assez robuste.Si vous souhaitez annuler votre propre bien, vous pouvez utiliser le format xml.dom.nœud childNode membre de manière récursive, de la résiliation lorsque le noeud.childNode = None.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top