Skip to content

Instantly share code, notes, and snippets.

@favila
Created March 19, 2013 08:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save favila/5194438 to your computer and use it in GitHub Desktop.
Save favila/5194438 to your computer and use it in GitHub Desktop.
Helper class for dealing with namespaces in elementtree (or any other situation where clark notation is used for qnames).
import re
# regular expressions for chars in an NCName
rCHARS = {
'startchar': u"_a-zA-Z"
u"\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-"
u"\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-"
u"\uFFFD\u10000-\uEFFFF",
'char': u"0-9\u00B7\u0300-\u036F\u203F-\u2040.-",
}
rPrefixedName = re.compile(u"(?P<prefix>[{startchar}][{startchar}{char}]*)"
u":(?P<localname>[{startchar}][{startchar}{char}]*)".format(**rCHARS))
class QNameMap(object):
"""Hold a mapping of prefixes to namespaces
Provides convenience methods to convert back and forth between them,
especially when using ElementTree.find* methods.
>>> Q = QNameMap({'ns':'http://example.org'})
>>> Q('ns:localname')
'{http://example.org}localname'
>>> Q.clarkify('.//ns:localname') # best used with et.find(Q.clarify(...))
'.//{http://example.org}localname'
"""
def __init__(self, nsmap):
self.map = nsmap
def __call__(self, qn):
"""Return clark notation version of a QName, even with blanks
Unlike QNameMap.qname(), this will also accept blank prefixes or
localnames.
>>> Q('ns:')
'http://example.org'
>>> Q(':name')
'name'
"""
prefix, localname = qn.split(':', 1)
if not prefix:
return localname
elif not localname:
return self.map[prefix]
else:
return self.qname(prefix, localname)
def qname(self, prefix, localname):
"""Return clark notation version of a QName"""
return '{{{}}}{}'.format(self.map[prefix], localname)
def clarkify(self, s):
"""Replace prefixed names with clark-notation fully-qualified names"""
return rPrefixedName.sub(lambda m: self.qname(**m.groupdict()), s)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment