In python 2.7 (with etree 1.3), I can suppress the XML prefixes on elements like this:
Python 2.7.1 (r271:86832, Jun 16 2011, 16:59:05) [GCC 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2335.15.00)] on darwin Type "help", "copyright", "credits" or "license" for more information. >>> import xml.etree.ElementTree as etree >>> etree.VERSION '1.3.0' >>> something = etree.Element('{http://some.namespace}token') >>> etree.tostring(something) '<ns0:token xmlns:ns0="http://some.namespace" />' >>> etree.register_namespace('', 'http://some.namespace') >>> etree.tostring(something) '<token xmlns="http://some.namespace" />'
The register_namespace
function was added in 1.3. I'm trying to remove the prefix in a way that is compatible with python 2.6's etree at version 1.2.6. Here's what I've tried:
Python 2.6.7 (r267:88850, Jul 31 2011, 19:30:54) [GCC 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2335.15.00)] on darwin Type "help", "copyright", "credits" or "license" for more information. >>> import xml.etree.ElementTree as etree >>> etree.VERSION '1.2.6' >>> something = etree.Element('{http://some.namespace}token') >>> etree.tostring(something) '<ns0:token xmlns:ns0="http://some.namespace" />' >>> etree._namespace_map['http://some.namespace'] = '' >>> etree.tostring(something) '<:token xmlns:="http://some.namespace" />'
This is not what I want. The prefixes are still there but are blank. Is there any way to remove them completely?
The namespace prefix is used as an alias for the complete namespace identifier. The parser sets XML-NAMESPACE-PREFIX before transferring control to the processing procedure when the operand of the XML PARSE statement is an alphanumeric data item and the RETURNING NATIONAL phrase is not specified.
To create an attribute that declares a namespace with a prefix, you create an attribute where the namespace of the name of the attribute is Xmlns, and the name of the attribute is the namespace prefix. The value of the attribute is the URI of the namespace.
XML Namespaces - The xmlns Attribute When using prefixes in XML, a namespace for the prefix must be defined. The namespace can be defined by an xmlns attribute in the start tag of an element. The namespace declaration has the following syntax. xmlns:prefix="URI".
An XML namespace is a collection of names that can be used as element or attribute names in an XML document. The namespace qualifies element names uniquely on the Web in order to avoid conflicts between elements with the same name.
After looking at the source code for ElementTree in python2.6, the :
is hard coded in the fixtag
function. As a workaround, here's what I did:
from xml.etree import ElementTree as etree if etree.VERSION[0:3] == '1.2': #in etree < 1.3, this is a workaround for supressing prefixes def fixtag(tag, namespaces): import string # given a decorated tag (of the form {uri}tag), return prefixed # tag and namespace declaration, if any if isinstance(tag, etree.QName): tag = tag.text namespace_uri, tag = string.split(tag[1:], "}", 1) prefix = namespaces.get(namespace_uri) if namespace_uri not in namespaces: prefix = etree._namespace_map.get(namespace_uri) if namespace_uri not in etree._namespace_map: prefix = "ns%d" % len(namespaces) namespaces[namespace_uri] = prefix if prefix == "xml": xmlns = None else: if prefix is not None: nsprefix = ':' + prefix else: nsprefix = '' xmlns = ("xmlns%s" % nsprefix, namespace_uri) else: xmlns = None if prefix is not None: prefix += ":" else: prefix = '' return "%s%s" % (prefix, tag), xmlns etree.fixtag = fixtag etree._namespace_map['http://some.namespace'] = None else: #For etree > 1.3, use register_namespace function etree.register_namespace('', 'http://some.namespace')
In case this post ever gets out of date, the code is maintained here.
I created a method at the top of my file and simply use it where the tag string should be. I named it 'ns_tag', but you could name it whatever you want.
def ns_tag(tag): return str( ElementTree.QName('http://some.namespace/api/4/', tag) )
Example:
root = ElementTree.fromstring(xml) success = root.find(ns_tag('success')) if success.text == 'true': for node in root.find(ns_tag('items')): id = node.find(ns_tag('id')).text ...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With