2

I have an XSD-file where I need to get a namespace as defined in the root-tag:

<schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:abw="http://www.liegenschaftsbestandsmodell.de/ns/abw/1.0.1.0" xmlns:adv="http://www.adv-online.de/namespaces/adv/gid/6.0" xmlns:bfm="http://www.liegenschaftsbestandsmodell.de/ns/bfm/1.0" xmlns:gml="http://www.opengis.net/gml/3.2" xmlns:sc="http://www.interactive-instruments.de/ShapeChange/AppInfo" elementFormDefault="qualified" targetNamespace="http://www.liegenschaftsbestandsmodell.de/ns/abw/1.0.1.0" version="1.0.1.0">
  <!-- elements -->
</schema>

Now as the targetNamespace of this schema-definition is "http://www.liegenschaftsbestandsmodell.de/ns/abw/1.0.1.0" I need to get the short identifier for this namespace - which is abw. To get this identifier I have to get that attribute from the root-tag that has the exact same value as my targetNamespace (I can´t rely on the identifier beeing part of the targetNamespace-string allready, this may change in the future).

On this question How to extract xml attribute using Python ElementTree I found how to get the value of an attribute given by its name. However I don´t know the attributes name, only its value, so what can I do when I have a value and want to select the attribute having this value?

I think of something like this:

for key in root.attrib.keys():
    if(root.attrib[key] == targetNamespace):
        return root.attrib[key]

but root.attrib only contains elementFormDefault, targetNamespace and version, but not xmlns:abw.

Community
  • 1
  • 1
MakePeaceGreatAgain
  • 35,491
  • 6
  • 60
  • 111

2 Answers2

1

string must be Unicode else error will appear

Traceback (most recent call last):
  File "<pyshell#62>", line 1, in <module>
    it = etree.iterparse(StringIO(xml))
TypeError: initial_value must be unicode or None, not str

code:

>>> from io import StringIO
>>> from xml.etree import ElementTree
>>> xml=u"""<schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:abw="http://www.liegenschaftsbestandsmodell.de/ns/abw/1.0.1.0" xmlns:adv="http://www.adv-online.de/namespaces/adv/gid/6.0" xmlns:bfm="http://www.liegenschaftsbestandsmodell.de/ns/bfm/1.0" xmlns:gml="http://www.opengis.net/gml/3.2" xmlns:sc="http://www.interactive-instruments.de/ShapeChange/AppInfo" elementFormDefault="qualified" targetNamespace="http://www.liegenschaftsbestandsmodell.de/ns/abw/1.0.1.0" version="1.0.1.0">
  <!-- elements -->
</schema>"""
>>> ns = dict([
    node for _, node in ElementTree.iterparse(
        StringIO(xml), events=['start-ns']
    )
])
>>> for k,v in ns.iteritems():
    if v=='http://www.liegenschaftsbestandsmodell.de/ns/abw/1.0.1.0':
        print k

output:

abw 
Hisham Karam
  • 1,288
  • 17
  • 28
  • This seems to work, however I don´t understand the dictionaries definition using the for-loop `node for _, node in ..`. – MakePeaceGreatAgain Oct 19 '16 at 08:28
  • @HimBromBeere look at name space section [link](http://effbot.org/zone/element-iterparse.htm) – Hisham Karam Oct 19 '16 at 08:34
  • @HimBromBeere `iterparse` return the `event `and `element` i ignored event . element as `tupel ` containing `namespace `and `value` the i converted the result into `dict ` for easy search – Hisham Karam Oct 19 '16 at 08:40
0

Using minidom instead of ETree did it:

import xml.dom.minidom as DOM
tree = DOM.parse(myFile)
root = tree.documentElement
targetNamespace = root.getAttribute("targetNamespace")

d = dict(root.attributes.items())
for key in d:
    if d[key] == targetNamespace: return key

This will return either targetNamespace or xmlns:abw depending on what comes first in the xsd. Of course we should ignore the first case, but this goes out of scope of this question.

MakePeaceGreatAgain
  • 35,491
  • 6
  • 60
  • 111