Question

Comment peut-on accéder NS attributs grâce à l'utilisation ElementTree?

ce qui suit:

<data xmlns="http://www.foo.net/a" xmlns:a="http://www.foo.net/a" book="1" category="ABS" date="2009-12-22">

Lorsque je tente de root.get ( « xmlns ») je reviens Aucun, la catégorie et la date sont très bien, Toute aide appréciée ..

Pas de solution correcte

Autres conseils

Je pense que element.tag est ce que vous cherchez. Notez que votre exemple manque un slash, il est donc déséquilibré et n'analyser. J'ai ajouté dans mon exemple.

>>> 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 vous voulez juste savoir l'URI xmlns, vous pouvez le diviser avec une fonction comme:

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

Pour beaucoup plus sur et les noms qualifiés namespaces dans ElementTree, consultez des exemples de effbot .

Regardez la documentation / exemples effbot espaces de noms; spécifiquement la fonction parse_map . Il vous montre comment ajouter un * ns_map * attribuer à chaque élément qui contient le préfixe / mappage URI applicable à cet élément spécifique.

Cependant, qui ajoute l'attribut ns_map à tous les éléments. Pour mes besoins, j'ai trouvé que je voulais une carte globale de tous les espaces de noms utilisés pour faire élément regarder en plus facile et non hardcoded.

Voici ce que je suis venu avec:

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

Avec cela, vous pouvez analyser un fichier xml et obtenir un dict avec les applications d'espace de noms. Donc, si vous avez un fichier xml comme ce qui suit ( "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>

Vous pourrez utiliser les namepaces xml et obtenir des informations pour des éléments comme 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'

Essayez ceci:

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)
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top