gavo.utils.stanxml module¶
A stan-like model for building namespaced XML trees.
The main reason for this module is that much of the VO’s XML mess is based on XML schema and thus has namespaced attributes. This single design decision ruins the entire XML design. To retain some rests of sanity, I treat the prefixes themselves as namespaces and maintain a single central registry from prefixes to namespaces in this module.
Then, the elements only use these prefixes, and this module makes sure that during serialization the instance document’s root element contains the namespace mapping (and the schema locations) required.
- class gavo.utils.stanxml.Element(id=None)[source]¶
Bases:
object
An element for serialization into XML.
This is loosely modelled after t.w.template stan.
Don’t add to the children attribute directly, use addChild or (more usually) __getitem__.
Elements have attributes and children. The attributes are defined, complete with defaults, in _a_<name> attributes as in AutoNodes. Attributes are checked.
Children are not usually checked, but you can set a _childSequence attribute containing a list of (unqualified) element names. These children will be emitted in the sequence given.
When deriving from Elements, you may need attribute names that are not python identifiers (e.g., with dashes in them). In that case, define an attribute _name_a_<att> and point it to any string you want as the attribute.
When serializing these, empty elements (i.e. those having an empty text and having no non-empty children) are usually discarded. If you need such an element (e.g., for attributes), set mayBeEmpty to True.
Since insane XSD mandates that local elements must not be qualified when elementFormDefault is unqualified, you need to set _local=True on such local elements to suppress the namespace prefix. Attribute names are never qualified here. If you need qualified attributes, you’ll have to use attribute name translation.
The content of the DOM may be anything recognized by addChild. In particular, you can give objects a serializeToXMLStan method returning strings or an Element to make them good DOM citizens.
Elements cannot harbor mixed content (or rather, there is only one piece of text).
- addAttribute(attName: str, attValue: str) None [source]¶
adds attName, attValue as a local attribute/value pair.
This is for when you have, if you will, “non-namespace” attributes (most of the time, xml namespace declarations).
If you set the same name multiple times, the last value set will win.
- addChild(child: Any) None [source]¶
adds child to the list of children.
Child may be an Element, a string, or a list or tuple of Elements and strings. Finally, child may be None, in which case nothing will be added.
- apply(func: Callable) Optional[Any] [source]¶
calls func(node, text, attrs, childIter).
This is a building block for tree traversals.
- clone()¶
returns a deep copy of self.
- isEmpty() bool [source]¶
returns true if the current node has no non-empty children and no non-whitespace text content.
- iterAttNames() Iterator[Tuple[str, str]] [source]¶
iterates over the defined attribute names of this node.
Each element returned is a pair of the node attribute name and the xml name (which may be translated via _a_name_<att>
- iterChildrenOfType(type: Type[SomeElement]) Iterator[SomeElement] [source]¶
iterates over all children having type.
- iterChildrenWithName(elName: str) Iterator[Any] [source]¶
iterates over children whose element name is elName.
This always does a linear search through the children and hence may be slow.
- name_ = None¶
- class gavo.utils.stanxml.NSRegistry[source]¶
Bases:
object
A container for a registry of namespace prefixes to namespaces.
This is used to have fixed namespace prefixes (IMHO the only way to have namespaced attribute values and retain sanity). The class is never instantiated. It is used through the module-level method registerPrefix.
- classmethod addNamespaceDeclarations(root: Element, prefixes: Set[str], prefixForEmpty: Optional[str] = None, includeSchemaLocation: bool = True) None [source]¶
adds xmlns declarations for prefixes to the stanxml node root.
With stanxml and the global-prefix scheme, xmlns declarations only come at the root element; thus, root should indeed be root rather than some random element.
- class gavo.utils.stanxml.NillableMixin[source]¶
Bases:
object
An Element mixin making the element XSD nillable.
This element will automatically have an xsi:nil=”true” attribute on empty elements (rather than leave them out entirely).
This overrides apply, so the mixin must be before the base class in the inheritance list.
- class gavo.utils.stanxml.Stub(dest: str)[source]¶
Bases:
object
A sentinel class for embedding objects not yet existing into stanxml trees.
These have a single opaque object and need to be dealt with by the user. One example of how these can be used is the ColRefs in stc to utype conversion.
Stubs are equal to each othter if their handles are identical.
- apply(func: Callable) None [source]¶
does nothing.
Stubs don’t have what Element.apply needs, so we don’t even pretend.
- name_ = 'stub'¶
- text_ = None¶
- class gavo.utils.stanxml.WriteBuffer(raw: Any, bufSize: int = 8192)[source]¶
Bases:
object
a very simple write buffer, collecting strings and handing them through to an actual files in suitably large chunks.
This ought to help make our XML writing to twisted requests a bit more wire-efficient.
The raw argument of course can’t be Any, it needs to be a binary-writable thing. I’m not giving a proper type because what’s here most of the time is a twisted web Request. The incomplete implementation of an io writer is also why this class exists in the first place.
- gavo.utils.stanxml.getPrefixInfo(prefix: str) Tuple[str, Optional[str]] ¶
- gavo.utils.stanxml.registerPrefix(prefix: str, ns: str, schemaLocation: Optional[str]) None ¶
- gavo.utils.stanxml.schemaURL(xsdName: str) str [source]¶
returns the URL to the local mirror of the schema xsdName.
This is used by the various xmlstan clients to make schemaLocations.
- gavo.utils.stanxml.xmlrender(tree: Element, prolog: str = '', prefixForEmpty: Optional[Any] = None) bytes [source]¶
returns a unicode object containing tree in serialized forms.
tree should be a stanxml.Element. Anything else will be phased out.
If prolog is given, it must be a string that will be prepended to the serialization of tree. The way ElementTree currently is implemented, you can use this for xml declarations or stylesheet processing instructions.
- gavo.utils.stanxml.xmlwrite(root: ~gavo.utils.stanxml.Element, outputFile: ~typing.BinaryIO, prefixForEmpty: ~typing.Optional[str] = None, nsRegistry: ~typing.Type[~gavo.utils.stanxml.NSRegistry] = <class 'gavo.utils.stanxml.NSRegistry'>, xmlDecl: bool = True, includeSchemaLocation: bool = True, prolog: ~typing.Optional[str] = None) None [source]¶
writes an xmlstan tree starting at root to outputFile.
prefixForEmpty is a namespace URI that should have no prefix at all.
outputFile must be opened in binary mode.