resueltos recorrer lista elementos ejercicios diccionarios diccionario dentro convertir anidados agregar python xml dictionary

recorrer - lista de diccionarios python



¿Editando XML como un diccionario en python? (8)

Intento generar archivos xml personalizados a partir de un archivo xml de plantilla en python.

Conceptualmente, quiero leer en la plantilla xml, eliminar algunos elementos, cambiar algunos atributos de texto y escribir el nuevo xml en un archivo. Yo quería que funcionara algo como esto:

conf_base = ConvertXmlToDict(''config-template.xml'') conf_base_dict = conf_base.UnWrap() del conf_base_dict[''root-name''][''level1-name''][''leaf1''] del conf_base_dict[''root-name''][''level1-name''][''leaf2''] conf_new = ConvertDictToXml(conf_base_dict)

ahora quiero escribir en el archivo, pero no veo cómo llegar a ElementTree.ElementTree.write ()

conf_new.write(''config-new.xml'')

¿Hay alguna forma de hacer esto o alguien puede sugerir que lo haga de otra manera?


¿Has probado esto?

print xml.etree.ElementTree.tostring( conf_new )


No estoy seguro si primero es más fácil convertir el conjunto de información en dictados anidados. Usando ElementTree, puedes hacer esto:

import xml.etree.ElementTree as ET doc = ET.parse("template.xml") lvl1 = doc.findall("level1-name")[0] lvl1.remove(lvl1.find("leaf1") lvl1.remove(lvl1.find("leaf2") # or use del lvl1[idx] doc.write("config-new.xml")

ElementTree fue diseñado para que no tenga que convertir sus árboles XML en listas y atributos primero, ya que usa exactamente eso internamente.

También es compatible como un pequeño subconjunto de XPath .


La forma más directa para mí:

root = ET.parse(xh) data = root.getroot() xdic = {} if data > None: for part in data.getchildren(): xdic[part.tag] = part.text


Mi modificación de la respuesta de Daniel, para dar un diccionario marginalmente más ordenado:

def xml_to_dictionary(element): l = len(namespace) dictionary={} tag = element.tag[l:] if element.text: if (element.text == '' ''): dictionary[tag] = {} else: dictionary[tag] = element.text children = element.getchildren() if children: subdictionary = {} for child in children: for k,v in xml_to_dictionary(child).items(): if k in subdictionary: if ( isinstance(subdictionary[k], list)): subdictionary[k].append(v) else: subdictionary[k] = [subdictionary[k], v] else: subdictionary[k] = v if (dictionary[tag] == {}): dictionary[tag] = subdictionary else: dictionary[tag] = [dictionary[tag], subdictionary] if element.attrib: attribs = {} for k,v in element.attrib.items(): attribs[k] = v if (dictionary[tag] == {}): dictionary[tag] = attribs else: dictionary[tag] = [dictionary[tag], attribs] return dictionary

namespace es la cadena xmlns, incluidos los paréntesis, que ElementTree precede a todas las etiquetas, por lo que aquí la borré, ya que hay un espacio de nombres para todo el documento

NB que ajusté el xml sin procesar también, de modo que las etiquetas ''vacías'' produzcan a lo sumo una '''' propiedad de texto en la representación de ElementTree

spacepattern = re.compile(r''/s+'') mydictionary = xml_to_dictionary(ElementTree.XML(spacepattern.sub('' '', content)))

daría por ejemplo

{''note'': {''to'': ''Tove'', ''from'': ''Jani'', ''heading'': ''Reminder'', ''body'': "Don''t forget me this weekend!"}}

está diseñado para xml específico que es básicamente equivalente a json, debe manejar atributos de elementos tales como

<elementName attributeName=''attributeContent''>elementContent</elementName>

también

existe la posibilidad de fusionar el diccionario de atributos / subetiquetas de forma similar a como se combinan las repeticiones de las subetiquetas, aunque anidar las listas parece algo apropiado :-)


Para facilitar la manipulación de XML en Python, me gusta la biblioteca Beautiful Soup . Funciona de la siguiente manera:

Archivo XML de muestra:

<root> <level1>leaf1</level1> <level2>leaf2</level2> </root>

Código de Python:

from BeautifulSoup import BeautifulStoneSoup, Tag, NavigableString soup = BeautifulStoneSoup(''config-template.xml'') # get the parser for the xml file soup.contents[0].name # u''root''

Puede usar los nombres de nodo como métodos:

soup.root.contents[0].name # u''level1''

También es posible usar expresiones regulares:

import re tags_starting_with_level = soup.findAll(re.compile(''^level'')) for tag in tags_starting_with_level: print tag.name # level1 # level2

Agregar e insertar nuevos nodos es bastante sencillo:

# build and insert a new level with a new leaf level3 = Tag(soup, ''level3'') level3.insert(0, NavigableString(''leaf3'') soup.root.insert(2, level3) print soup.prettify() # <root> # <level1> # leaf1 # </level1> # <level2> # leaf2 # </level2> # <level3> # leaf3 # </level3> # </root>


XML tiene un rico infoset, y se necesitan algunos trucos especiales para representarlo en un diccionario de Python. Los elementos se ordenan, los atributos se distinguen de los elementos, etc.

Un proyecto para manejar viajes de ida y vuelta entre diccionarios XML y Python, con algunas opciones de configuración para manejar las compensaciones de diferentes maneras, es el Soporte de XML en las herramientas de escabechado . Se requiere la versión 1.3 y más reciente. No es puro Python (y de hecho está diseñado para facilitar la interacción con C ++ / Python), pero podría ser apropiado para varios casos de uso.


Esto te dará un dict menos atributos ... no sé si esto es útil para cualquiera. Estaba buscando una solución xml to dict cuando se me ocurrió esto.

import xml.etree.ElementTree as etree tree = etree.parse(''test.xml'') root = tree.getroot() def xml_to_dict(el): d={} if el.text: d[el.tag] = el.text else: d[el.tag] = {} children = el.getchildren() if children: d[el.tag] = map(xml_to_dict, children) return d

Esto: http://www.w3schools.com/XML/note.xml

<note> <to>Tove</to> <from>Jani</from> <heading>Reminder</heading> <body>Don''t forget me this weekend!</body> </note>

Sería igual a esto:

{''note'': [{''to'': ''Tove''}, {''from'': ''Jani''}, {''heading'': ''Reminder''}, {''body'': "Don''t forget me this weekend!"}]}


Añadiendo esta línea

d.update((''@'' + k, v) for k, v in el.attrib.iteritems())

en el código del usuario247686 también puede tener atributos de nodo.

Lo encontré en esta publicación https://.com/a/7684581/1395962

Ejemplo:

import xml.etree.ElementTree as etree from urllib import urlopen xml_file = "http://your_xml_url" tree = etree.parse(urlopen(xml_file)) root = tree.getroot() def xml_to_dict(el): d={} if el.text: d[el.tag] = el.text else: d[el.tag] = {} children = el.getchildren() if children: d[el.tag] = map(xml_to_dict, children) d.update((''@'' + k, v) for k, v in el.attrib.iteritems()) return d

Llamar como

xml_to_dict(root)