10

I use python 2.7 with the lib ElementTree.

I can't use lxml lib.

I need to get the namespaces in a string namespace_string. In order to fill my namespace dictionary.

my xml:

<?xml version="1.0" encoding="UTF-8"?>
<AX_Bestandsdatenauszug
    xmlns="http://www.adv-online.de/namespaces/adv/gid/6.0"
    xmlns:adv="http://www.adv-online.de/namespaces/adv/gid/6.0"
    xmlns:gco="http://www.isotc211.org/2005/gco"
    xmlns:gmd="http://www.isotc211.org/2005/gmd"
    xmlns:gml="http://www.opengis.net/gml/3.2"
    xmlns:ows="http://www.opengis.net/ows"
    xmlns:wfs="http://www.adv-online.de/namespaces/adv/gid/wfs"
    xmlns:wfsext="http://www.adv-online.de/namespaces/adv/gid/wfsext"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    xmlns:xlink="http://www.w3.org/1999/xlink"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:ogc="http://www.adv-online.de/namespaces/adv/gid/ogc"
    xsi:schemaLocation="http://www.adv-online.de/namespaces/adv/gid/6.0 NAS-Operationen.xsd">

    <enthaelt>
            <gml:featureMember>
            <xmlstuff>....a lot of xml stuff....</xmlstuff>
            </gml:featureMember>
    </enthaelt>
</AX_Bestandsdatenauszug>

code:

import clr
import sys

clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *
sys.path.append("C:\Program Files (x86)\IronPython 2.7\Lib")
import xml.etree.ElementTree as ET
from io import StringIO


xml="file.xml"

tree = ET.parse(xml)
root = tree.getroot()


my_schema = "namespace_string"

my_namespaces = dict([node for _, node in ET.iterparse(StringIO(my_schema), events=['start-ns'])])

The code for the dictionary is from this answer:https://stackoverflow.com/a/37409050/7317684

I tryed namespace_string=root.tag but this get me only ="{http://www.adv-online.de/namespaces/adv/gid/6.0}AX_Bestandsdatenauszug"

Found only lxml solutions:(

Any help would be great!

0

2 Answers 2

14

The code for creating a dictionary with all the declared namespaces can be made quite simple. This is all that is needed:

import xml.etree.ElementTree as ET

my_namespaces = dict([node for _, node in ET.iterparse('file.xml',
                                                        events=['start-ns'])])

You don't need to use StringIO or open(). Just provide the XML filename as an argument to iterparse().

Each item provided by iterparse() is an (event, (prefix, namespace-uri)) tuple. The start-ns event is not described in the Python 2.7 documentation of iterparse (but it is mentioned in the corresponding Python 3 documentation).


Note: the code above works in CPython and Jython, but not in IronPython. See https://github.com/IronLanguages/main/issues/968.

Sign up to request clarification or add additional context in comments.

2 Comments

I forgot to mention, that i use IronPython 2.7. I didn't know thats this was important. I got a error that say: IronPython don't support iterparse. But oddly that was not the case with the code of saurabhsuman the error did not occur.
It should work with IronPython 2.7.9. See github.com/IronLanguages/ironpython2/issues/370.
3

You should pass the contents of the xml file in ET.iterparse() instead of string my_schema.

Change your code to:

from io import StringIO
import xml.etree.ElementTree as ET

xml = "file.xml"
f = open(xml, "r")
xml_data = unicode(f.read() , "utf-8") 
my_namespaces = dict([node for _, node in ET.iterparse(StringIO(xml_data), events=['start-ns'])])

from pprint import pprint
pprint(my_namespaces)

Output:

{'': 'http://www.adv-online.de/namespaces/adv/gid/6.0',
 u'adv': 'http://www.adv-online.de/namespaces/adv/gid/6.0',
 u'gco': 'http://www.isotc211.org/2005/gco',
 u'gmd': 'http://www.isotc211.org/2005/gmd',
 u'gml': 'http://www.opengis.net/gml/3.2',
 u'ogc': 'http://www.adv-online.de/namespaces/adv/gid/ogc',
 u'ows': 'http://www.opengis.net/ows',
 u'wfs': 'http://www.adv-online.de/namespaces/adv/gid/wfs',
 u'wfsext': 'http://www.adv-online.de/namespaces/adv/gid/wfsext',
 u'xlink': 'http://www.w3.org/1999/xlink',
 u'xsd': 'http://www.w3.org/2001/XMLSchema',
 u'xsi': 'http://www.w3.org/2001/XMLSchema-instance'}

6 Comments

Thx for your help, but i got a ValueError: write to closed file in this line: my_namespaces = dict([node for _, node in ET.iterparse(StringIO(xml_data), events=['start-ns'])]).
can you check now with the edited code, the line my_namespaces = dict([node for _, node in ET.iterparse(StringIO(xml_data), events=['start-ns'])]) should be within with block.
The same error in the same line appears with the codeline in the block.
can you check now with the edited code, it is working on my side
Can you post the stack trace
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.