Accediendo atributo xmlns con Python elementtree?
-
21-09-2019 - |
Pregunta
¿Cómo se puede acceder a través de los atributos NS usando elementtree?
Con el siguiente:
<data xmlns="http://www.foo.net/a" xmlns:a="http://www.foo.net/a" book="1" category="ABS" date="2009-12-22">
Cuando intento root.get ( 'xmlns') que vuelva Ninguno, categoría y fecha están bien, Cualquier ayuda apreciado ..
No hay solución correcta
Otros consejos
Creo element.tag
es lo que estás buscando. Tenga en cuenta que el ejemplo no se encuentra una barra al final, por lo que es desproporcionado o no va a analizar. He añadido una en mi ejemplo.
>>> from xml.etree import ElementTree as ET
>>> data = '''<data xmlns="http://www.foo.net/a"
... xmlns:a="http://www.foo.net/a"
... book="1" category="ABS" date="2009-12-22"/>'''
>>> element = ET.fromstring(data)
>>> element
<Element {http://www.foo.net/a}data at 1013b74d0>
>>> element.tag
'{http://www.foo.net/a}data'
>>> element.attrib
{'category': 'ABS', 'date': '2009-12-22', 'book': '1'}
Si lo que desea es conocer las xmlns URI, puede dividir a cabo con una función como:
def tag_uri_and_name(elem):
if elem.tag[0] == "{":
uri, ignore, tag = elem.tag[1:].partition("}")
else:
uri = None
tag = elem.tag
return uri, tag
Para mucho más en espacios de nombres y nombres cualificados en elementtree, ver ejemplos de effbot .
vistazo a la documentación espacios de nombres effbot / ejemplos; específicamente la href="http://effbot.org/zone/element-namespaces.htm" rel="noreferrer"> parse_map función Sin embargo, añade que el atributo ns_map a todos los elementos. Para mis necesidades, me di cuenta de que quería un mapa global de todos los espacios de nombres utilizados para hacer más fácil elemento de mirar hacia arriba y no codificado. Esto es lo que ocurrió: Con esto se puede analizar un archivo XML y obtener un diccionario con las asignaciones de espacio de nombres. Por lo tanto, si usted tiene un archivo XML como el siguiente ( "my.xml"): Usted será capaz de utilizar las namepaces XML y obtener información para elementos como dc: creator import elementtree.ElementTree as ET
def parse_and_get_ns(file):
events = "start", "start-ns"
root = None
ns = {}
for event, elem in ET.iterparse(file, events):
if event == "start-ns":
if elem[0] in ns and ns[elem[0]] != elem[1]:
# NOTE: It is perfectly valid to have the same prefix refer
# to different URI namespaces in different parts of the
# document. This exception serves as a reminder that this
# solution is not robust. Use at your own peril.
raise KeyError("Duplicate prefix with different URI found.")
ns[elem[0]] = "{%s}" % elem[1]
elif event == "start":
if root is None:
root = elem
return ET.ElementTree(root), ns
<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0"
xmlns:content="http://purl.org/rss/1.0/modules/content/"
xmlns:dc="http://purl.org/dc/elements/1.1/"\
>
<feed>
<item>
<title>Foo</title>
<dc:creator>Joe McGroin</dc:creator>
<description>etc...</description>
</item>
</feed>
</rss>
>>> tree, ns = parse_and_get_ns("my.xml")
>>> ns
{u'content': '{http://purl.org/rss/1.0/modules/content/}',
u'dc': '{http://purl.org/dc/elements/1.1/}'}
>>> item = tree.find("/feed/item")
>>> item.findtext(ns['dc']+"creator")
'Joe McGroin'
Prueba esto:
import xml.etree.ElementTree as ET
import re
import sys
with open(sys.argv[1]) as f:
root = ET.fromstring(f.read())
xmlns = ''
m = re.search('{.*}', root.tag)
if m:
xmlns = m.group(0)
print(root.find(xmlns + 'the_tag_you_want').text)