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ó:

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

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"):

<?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>

Usted será capaz de utilizar las namepaces XML y obtener información para elementos como dc: creator

>>> 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)
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top