J'ai une liste avec d'autres listes et dicts, par ex.

data = [
        {"id": 0,
        "name": "Room #0",
        "students": [
            {
                "id": 345,
                "name": "William Perez"
            },
            {
                "id": 976,
                "name": "Daniel Smith"
            },
            ...
        },
        ...
    ]

json.dumps() peut l'analyser automatiquement et créer un fichier .json. XML et JSON ont une grammaire différente, mais peut-être existe-t-il un moyen d'analyser cette liste et de créer automatiquement une arborescence XML ? Ou je dois le construire manuellement ?

-1
Pavel Antspovich 7 févr. 2020 à 16:23

1 réponse

Meilleure réponse

Bien sûr, mais puisqu'il n'y a pas une seule façon de mapper les choses sur les attributs par rapport aux sous-éléments, vous devrez le découvrir vous-même … ou simplement créer des éléments et espérer le meilleur, comme ci-dessous.

J'ai ajouté une affordance pour définir la balise XML d'un dict avec _tag.

import xml.etree.ElementTree as et


def emit_xml(tree, obj, tag="object"):
    if isinstance(obj, list):
        for ent in obj:
            emit_xml(tree, ent, tag)
    elif isinstance(obj, dict):
        obj = obj.copy()
        tag = obj.pop("_tag", tag)
        tree = et.SubElement(tree, tag)
        for key, value in obj.items():
            emit_xml(tree, value, tag=key)
    else:
        et.SubElement(tree, tag).text = str(obj)


data = [
    {
        "_tag": "room",
        "id": 0,
        "name": "Room #0",
        "students": [
            {"id": 345, "name": "William Perez"},
            {"id": 976, "name": "Daniel Smith"},
        ],
    },
    {
        "_tag": "room",
        "id": 1,
        "name": "Room #1",
        "students": [
            {"id": 357357, "name": "Wirelliam Pez"},
            {"id": 7222, "name": "Del Smitanih"},
        ],
    },
]

root = et.Element("root")
emit_xml(root, data)
print(et.tostring(root, encoding="unicode"))

Les sorties

<root>
  <room>
    <id>0</id>
    <name>Room #0</name>
    <students>
      <id>345</id>
      <name>William Perez</name>
    </students>
    <students>
      <id>976</id>
      <name>Daniel Smith</name>
    </students>
  </room>
  <room>
    <id>1</id>
    <name>Room #1</name>
    <students>
      <id>357357</id>
      <name>Wirelliam Pez</name>
    </students>
    <students>
      <id>7222</id>
      <name>Del Smitanih</name>
    </students>
  </room>
</root>
2
AKX 7 févr. 2020 à 13:32