8

I tried to register namespace with this:

ET.register_namespace("inv", "http://www.stormware.cz/schema/version_2/invoice.xsd")

but it doesn't work:

Traceback (most recent call last):
  File "C:\tutorial\temp_xml2.py", line 34, in module>
    for listInvoice in root.findall('inv:invoiceHeader'):
  File "C:\Python27\LIB\xml\etree\ElementTree.py", line 390, in findall
    return ElementPath.findall(self, path, namespaces)
  File "C:\Python27\LIB\xml\etree\ElementPath.py", line 293, in findall
    return list(iterfind(elem, path, namespaces))
  File "C:\Python27\LIB\xml\etree\ElementPath.py", line 259, in iterfind
    token = next()
  File "C:\Python27\LIB\xml\etree\ElementPath.py", line 83, in xpath_tokenizer
    raise SyntaxError("prefix %r not found in prefix map" % prefix)
SyntaxError: prefix 'inv' not found in prefix map
>>>

what's wrong with this?


Thanks Martinj

I tried - 1.:

for listInvoice in root.findall('inv:invoiceHeader', namespaces=dict(inv='http://www.stormware.cz/schema/version_2/invoice.xsd')):
    invoiceHeader = listInvoice.find('inv:id', namespaces=dict(inv='http://www.stormware.cz/schema/version_2/invoice.xsd')).text
    print invoiceHeader

Result: (empty)

2.:

nsmap=root.nsmap
print nsmap

Result: AttributeError: 'Element' object has no attribute 'nsmap'

3.:

for listInvoice in root.findall('.//{http://www.stormware.cz/schema/version_2/invoice.xsd}invoiceHeader'):
    invoiceHeader = listInvoice.find('.//{http://www.stormware.cz/schema/version_2/invoice.xsd}id').text
    print invoiceHeader

Result: Works ok.

Is there any chance to register namespaces at once? Then I would like to use listInvoice.find('inv:id').text instead of listInvoice.find('.//{http://www.stormware.cz/schema/version_2/invoice.xsd}id').text (nicer code and easy to read)

1

1 Answer 1

19

It looks like the documentation hasn't been updated on how to use namespaces and .findall().

The .findall() function (as well as .find(), .findtext() and.iterfind()) takes anamespaces` argument which is supposed to be a mapping. That is the only structure consulted when finding tags:

root.findall('inv:invoiceHeader', namespaces=dict(inv='http://www.stormware.cz/schema/version_2/invoice.xsd'))

The .register_namespace() function is only useful for when serializing a tree out to text again.

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

2 Comments

Thanks, this works! For .get() I needed to prefix with {namespace-URL}, e.g. element.get({http://www.w3.org/1999/02/22-rdf-syntax-ns#}ID).
@Vincent: yes, attribute access has no support for namespace prefix translation and you need to pass in the fully qualified namespace prefix.

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.