6.2.3. XML: Namespaces

6.2.3.1. Documents and Elements

class pyslet.xml.namespace.NSNode(parent=None)

Bases: pyslet.xml.structures.Node

Base class for NSElement and Document shared attributes.

This class adds a number of method for managing the mapping between namespace prefixes and namespace URIs in both elements and in the document itself.

You don’t have to worry about using these, they are called automatically enabling the transparent serialisation of XML elements with appropriately defined namespace prefixes. You only need to use these method if you wish to customise the way the mapping is done. The most likely use case is simply to call make_prefix() at the document level to add an explicit declaration of any auxiliary namespaces, typically done by the __init__ method on classes derived from NSDocument.

get_prefix(ns)

Returns the prefix assigned to a namespace

ns
The namespace URI as a character string.

Returns None if no prefix is currently in force for this namespace.

get_ns(prefix='')

Returns the namespace associated with prefix.

prefix
The prefix to search for, the empty string denotes the default namespace.

This method searches back through the hierarchy until it finds the namespace in force or returns None if no definition for this prefix can be found.

In the special case of prefix being ‘xml’ the XML namespace itself is returned. See XML_NAMESPACE.

new_prefix(stem='ns')

Return an unused prefix

stem
The returned value will be of the form stem# where # is a number used in sequence starting with 1. This argument defaults to ns so, by default, the prefixes ns1, ns2, ns3, etc. are used.
make_prefix(ns, prefix=None)

Creates a new mapping for a namespace

ns
The namespace being mapped
prefix

The character string representing the namespace in qualified names (without the colon). This parameter is optional, if no value is provided then a new randomly generated prefix is used using new_prefix().

Note that an empty string denotes the default namespace, which will appear simply as xmlns=<ns> in the element’s tag.

If the prefix has already been declared for this node then ValueError is raised.

get_prefix_map()

Returns the complete prefix to ns mapping in force

Combines the prefix mapping for this element with that of it’s parents. Returns a dictionary mapping prefix strings to the URIs of the namespaces they represent.

write_nsattrs(attributes, escape_function=<function escape_char_data>, root=False, **kws)

Adds strings representing any namespace attributes

See write_xml_attributes() for details of argument usage.

This method is defined for both NSDocument and NSElement and it prefixes the attribute list with any XML namespace declarations that are defined by this node. If root is True then all namespace declarations that are in force are written, not just those attached to this node. See get_prefix_map() for more information.

GetPrefix(*args, **kwargs)

Deprecated equivalent to get_prefix()

MakePrefix(*args, **kwargs)

Deprecated equivalent to make_prefix()

class pyslet.xml.namespace.NSDocument(root=None, base_uri=None, req_manager=None, **kws)

Bases: pyslet.xml.structures.Document, pyslet.xml.namespace.NSNode

default_ns = None

The default namespace for this document class

A special class attribute used to set the default namespace for elements created within the document that are parsed without an effective namespace declaration. Set to None, but typically overridden by derived classes.

XMLParser(entity)

Namespace documents use the special XMLNSParser.

classmethod get_element_class(name)

Returns a class object suitable for representing <name>

name is a tuple of (namespace, name), this overrides the behaviour of Document, in which name is a string.

The default implementation returns NSElement.

class pyslet.xml.namespace.NSElement(parent, name=None)

Bases: pyslet.xml.namespace.NSNode, pyslet.xml.structures.Element

Element class used for namespace-aware elements.

Namespace aware elements have special handling for elements that contain namespace declarations and for handling qualified names. A qualified name is a name that starts with a namespace prefix followed by a colon, for example “md:name” might represent the ‘name’ element in a particular namespace indicated by the prefix ‘md’.

The same element could equally be encountered with a different prefix depending on the namespace declarations in the document. As a result, to interpret element (and attribute) names they must be expanded.

An expanded name is represented as a 2-tuple consisting of two character strings, the first is a URI of a namespace (used only as an identifier, the URI does not have to be the URI of an actual resource). The second item is the element name defined within that namespace.

In general, when dealing with classes derived from NSElement you should use expanded names wherever you would normally use a plain character string. For example, the class attribute XMLNAME, used by derived classes to indicate the default name to use for the element the class represents must be an expanded name:

class MyElement(NSElement):
    XMLNAME = ('http://www.example.com/namespace', 'MyElement')

Custom attribute mappings use special class attributes with names starting with XMLATTR_ and this mechanism cannot be extended to use the expanded names. As a result these mappings can only be used for attributes that have no namespace. In practice this is not a significant limitation as attributes are usually defined this way in XML documents. Note that the special XML attributes (which appear to be in the namespace implicitly decared by the prefix “xml:”) should be referenced using the special purpose get/set methods provided.

set_xmlname(name)

Sets the name of this element

Overridden to support setting the name from either an expanded name or an unqualified name (in which case the namespace is set to None).

get_xmlname()

Returns the name of this element

For classes derived from NSElement this is always an expanded name (even if the first component is None, indicating that the namespace is not known.

classmethod mangle_aname(name)

Returns a mangled attribute name

Custom setters are enabled only for attributes with no namespace. For attriubtes from other namespaces the default processing defined by the Element’s set_attribute/get_attribute(s) implementation is used.

classmethod unmangle_aname(mname)

Overridden to return an expanded name.

Custom attribute mappings are only supported for attributes with no namespace.

set_attribute(name, value)

Sets the value of an attribute.

Overridden to allow attributes to be set using either expanded names (2-tuples) or unqualified names (character strings).

Implementation notes: for elements descended from NSElement all attributes are stored using expanded names internally. The method unmangle_name() is overridden to return a 2-tuple to make their ‘no namespace’ designation explicit.

This method also catches the new namespace prefix mapping for the element which is placed in a special attribute by XMLNSParser.parse_nsattrs() and updates the element’s namespace mappings accordingly.

get_attribute(name)

Gets the value of an attribute.

Overridden to allow attributes to be got using either expanded names (2-tuples) or unqualified names (character strings).

pyslet.xml.namespace.map_class_elements(class_map, scope, ns_alias_table=None)

Adds element name -> class mappings to class_map

class_map
A dictionary that maps XML element expanded names onto class objects that should be used to represent them.
scope
A dictionary, or an object containing a __dict__ attribute, that will be scanned for class objects to add to the mapping. This enables scope to be a module. The search is not recursive, to add class elements from imported modules you must call map_class_elements for each module.
ns_alias_table

Used to create multiple mappings for selected element classes based on namespace aliases. It is a dictionary mapping a canonical namespace to a list of aliases. For example, if:

ns_alias_table={'http://www.example.com/schema-v3': [
                    'http://www.example.com/schema-v2',
                    'http://www.example.com/schema-v1']}

An element class with:

XMLNAME = ('http://www.example.com/schema-v3', 'data')

would then be used by the parser to represent the <data> element in the v1, v2 and v3 schema variants.

The scope is searched for classes derived from NSElement that have an XMLNAME attribute defined. It is an error if a class is found with an XMLNAME that has already been mapped.

6.2.3.1.1. Backwards Compatibility

class pyslet.xml.namespace.XMLNSDocument

Alias for NSDocument

class pyslet.xml.namespace.XMLNSElement

Alias for NSElement

6.2.3.2. Namespace URIs

pyslet.xml.namespace.XML_NAMESPACE = 'http://www.w3.org/XML/1998/namespace'

URI string constant for the special XML namespace

pyslet.xml.namespace.XMLNS_NAMESPACE = 'http://www.w3.org/2000/xmlns/'

URI string constant for the special XMLNS namespace

pyslet.xml.namespace.NO_NAMESPACE = '~'

Special string constant used to represent no namespace

pyslet.xml.namespace.match_expanded_names(xname, xmatch, ns_aliases=None)

Compares two expanded names

xname, xmatch
Expanded names, i.e., 2-tuples of character strings containing (namespace URI, element name).
ns_aliases

Used to match multiple names based on namespace aliases. It is a list of namespaces that should be treated as equivalent to the namespace of xname. For example:

match_expanded_names(
    ('http://www.example.com/schema-v3','data'),
    ('http://www.example.com/schema-v1','data'),
    ['http://www.example.com/schema-v2',
     'http://www.example.com/schema-v1'])

returns True as xmatch uses an allowed alias for the namespace of xname.

6.2.3.3. Parsing

pyslet.xml.namespace.is_valid_ncname(name)

Checks a string against NCName

class pyslet.xml.namespace.XMLNSParser(entity=None)

Bases: pyslet.xml.parser.XMLParser

A special parser for parsing documents that may use namespaces.

classmethod register_nsdoc_class(doc_class, xname)

Registers a document class

Internally XMLNSParser maintains a single table of document classes which can be used to identify the correct class to use to represent a document based on the expanded name of the root element.

doc_class
the class object being registered, it must be derived from NSDocument
xname
A tuple of (namespace, name) representing the name of the root element. If either (or both) components are None a wildcard is registered that will match any corresponding value.
get_nsdoc_class(xname)

Returns a doc class object suitable for this root element

xname
An expanded name.

Returns a class object derived from NSDocument suitable for representing a document with a root element with the given expanded name.

This default implementation uses xname to locate a class registered with register_nsdoc_class(). If an exact match is not found then wildcard matches are tried matching only the namespace and root element name in turn.

A wildcard match is stored in the mapping table either as an expanded name of the form (<uri string>, None) or (None, <element name>). The former is preferred as it enables a document class to be defined that is capable of representing a document with any root element from the given namespace (a common use case) and is thus always tried first.

If no document class can be found, NSDocument is returned.

expand_qname(qname, ns_defs, use_default=True)

Expands a QName, returning a (namespace, name) tuple.

qname
The qualified name
ns_defs

A mapping of prefix to namespace URI used to expand the name

If ns_defs does not contain a suitable namespace definition then the context’s existing prefix mapping is used, then its parent’s mapping is used, and so on.

use_default (defaults to True)

Whether or not to return the default namespace for an unqualified name.

If use_default is False an unqualified name is returned with NO_NAMESPACE as the namespace (this is used when expanding attribute names).

match_xml_name(element, qname)

Tests if qname is a possible name for this element.

This method is used by the parser to determine if an end tag is the end tag of this element.

parse_nsattrs(attrs)

Manages namespace prefix mappings

Takes a dictionary of attributes as returned by parse_stag() and finds any namespace prefix mappings returning them as a dictionary of prefix:namespace suitable for passing to expand_qname(). It also removes the namespace declarations from attrs and expands the attribute names into (ns, name) pairs.

Implementation note: a special attribute called ‘.ns’ (in no namespace) is set to the parsed prefix mapping dictionary enabling the prefix mapping to be passed transparently to NSElement.set_attribute() by py:class:XMLParser.

get_stag_class(qname, attrs=None)

[40] STag

Overridden to allow for namespace handling.

6.2.3.4. Exceptions

class pyslet.xml.namespace.XMLNSError

Bases: pyslet.xml.parser.XMLFatalError

Raised when an illegal QName is found.