Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Suppressing namespace prefixes in ElementTree 1.2

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?

like image 652
jterrace Avatar asked Nov 13 '11 17:11

jterrace


People also ask

What is namespace prefix in XML?

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.

How do I add namespace prefix to XML element?

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.

What is the correct way of declaring an XML 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".

What is the purpose of namespace in XML?

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.


2 Answers

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.

like image 120
jterrace Avatar answered Sep 24 '22 00:09

jterrace


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         ... 
like image 44
Ryan Anguiano Avatar answered Sep 22 '22 00:09

Ryan Anguiano