Mi modificación de la respuesta de Daniel, para dar una marginall y más ordenado diccionario:
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
espacio de nombres es la cadena xmlns, incluyendo los apoyos, que elementtree antepone a todas las etiquetas, así que aquí se han limpiado ya que hay un espacio de nombres para todo el documento
NB que yo ajustó el código XML sin demasiado, por lo que las etiquetas 'vacías' produciría a lo sumo un '' propiedad de texto en la representación 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!"}}
que está diseñado para XML específico que es básicamente equivalente a JSON, debe manejar elemento de atributos tales como
<elementName attributeName='attributeContent'>elementContent</elementName>
demasiado
existe la posibilidad de fusionar el diccionario diccionario atributo/etiqueta secundaria de manera similar a subetiquetas cómo repetición se fusionan, aunque anidar las listas parece algo apropiado :-)
BeautifulSoup convierte todo en minúsculas. Eso realmente apesta. ¡Tengo que preservar los casos de etiquetas y valores! – user236215
El autor de BeautifulSoup dice que hace esto porque HTMLParser lo hace. "Si necesita conservar el caso de etiqueta, intente lxml". – nealmcb