pxdom

pxdom 1.1
A Python DOM implementation

pxdom is a W3C DOM Level 3 implementation with Python and OMG-style (_get/_set) bindings. All features described in the Core and LS Recommendations are supported, with the following exceptions:

pxdom runs on Python 1.5.2 or later, but certain features are dependent on Python version:

Installation

Copy pxdom.py into any folder in your Python path, for example /usr/lib/python/site-packages or C:\Python23\Lib\site-packages.

pxdom can also be included and imported as a submodule of another package. This is a good strategy if you wish to distribute a DOM-based application without having to worry about the version of Python or other XML tools installed.

The only dependencies are the standard library string-handling and URL-related modules.

Usage

The pxdom module implements the DOMImplementationSource interface from DOM Level 3 Core. So to parse a document from a file, use eg.:

import pxdom
dom= pxdom.getDOMImplementation('')
parser= dom.createLSParser(dom.MODE_SYNCHRONOUS, None)
doc= parser.parseURI('file:///f|/data/doc.xml')

For more on using DOM Level 3 Load to create documents from various sources, see the DOM Level 3 Load/Save specification.

Alternatively, the pxdom module offers the convenience functions parse and parseString, which work like the Python minidom module’s functions of the same names:

doc= pxdom.parse('F:\\data\\doc.xml')
doc= pxdom.parseString('<el attr="val">content</el>')

DOMConfiguration parameters

The result of the parse operation depends on the parameters set on the LSParser.domConfig mapping. By default, in accordance with the DOM specification, all CDATA sections will be replaced with plain text nodes and all bound entity references will be replaced by the contents of the entity referred to. This includes external entity references and the external subset.

If you use the parse and parseString functions, pxdom will set the parameter ‘cdata-sections’ to True, allowing CDATA sections to stay in the document, and the parameter ‘pxdom-resolve-resources’ to False so external entities and the external subset are left alone. This is to emulate the behaviour of the Python standard library’s minidom module.

If you prefer also to receive EntityReference nodes in your document, set the ‘entities’ parameter to a true value. For example:

parser= dom.createLSParser(dom.MODE_SYNCHRONOUS, None)
parser.domConfig.setParameter('cdata-sections', 1)
parser.domConfig.setParameter('entities', 1)
doc= parser.parseURI('file:///home/data/doc.xml')

Or, using the parse/parseString shortcut functions, you can pass in an optional dictionary of extra DOMConfiguration parameters to set, like:

doc= pxdom.parse('file:///home/data/doc.xml', {'entities': 1})

(Of course, this usage would no longer be minidom-compatible.) See the DOM 3 Core and Load/Save specifications for more DOMConfiguration parameters.

Extensions

pxdom supports some supplemental non-standard features. Their names are always prefixed with ‘pxdom’ to avoid confusion with the standard.

Extra DOMConfiguration parameters

Configuration parameters in DOM Level 3 may affect parsing, serialisation and normalisation operations. pxdom adds a few new parameters not defined in the specification.

If you want to set a pxdom extra parameter to a non-default value but still be compatible with any other DOM Level 3 implementation, you can use the DOMConfiguration.canSetParameter method to ensure that the parameter is supported first.

pxdom-resolve-resources

Applies to: parsing. Default: True (except with parse/parseString functions).

Dictates whether resources external to the document file will be resolved and used. This affects external entities and the DTD external subset.

pxdom uses only the SYSTEM identifier in fetching an external resource, so parsing an XHTML document, for example, would make many requests to the W3C server to grab the document type information. This is quite slow. Note also that at the time of writing the DTD referenced by XHTML 1.1 documents has acknowledged bugs in it, which pxdom is unable to parse. (This has been corrected for the forthcoming XHTML Modularization Second Edition specification.)

To do something with PUBLIC identifiers, such as supply local copies of DTDs, you would have to provide a standard DOM LSResourceResolver object to the configuration parameter ‘resource-resolver’. Resource resolvers will never be called if ‘pxdom-resolve-resources’ is set to false.

When the convenience functions parse and parseString are called, ‘pxdom-resolve-resources’ will be false by default, instead of true, for minidom compatibility.

pxdom-normalize-text

Applies to: normalisation. Default: True.

Dictates whether text node normalisation (as performed by the DOM Level 1 Core Node.normalize method) will take place when the DOM Level 3 Core Document.normalizeDocument method is called.

By default, matching the DOM specification, text node normalisation does occur, but pxdom allows this to be turned off if unwanted.

pxdom-update-entities

Applies to: normalisation. Default: True.

Dictates whether entity reference nodes have their content child nodes updated from the declaration stored in the doctype. This may result in descendants with different namespaces when the entity reference has been moved, if the entity contains prefixes whose namespaces are not declared in the entity.

By default, matching the DOM specification, entities are updated, but pxdom allows this to be turned off if unwanted.

pxdom-assume-element-content

Applies to: parsing, normalisation, serialisation, isElementContentWhitespace. Default: False.

In order to support the feature Text.isElementContentWhitespace, pxdom must know the content model of the particular element that contains the text node. Often this is only defined in the DTD external subset, which might have been omitted or not read.

Normally, following the infoset specification, pxdom will guess that elements with unknown content models do not contain ‘element content’ — so Text.isElementContentWhitespace will always return False for elements not mentioned in the DOCTYPE internal subset.

However, if the DOMConfiguration parameter ‘pxdom-assume-element-content’ is set to a true value, it will guess that unknown elements do contain element content, and so whitespace nodes inside them will be ‘element content whitespace’ (often referred to as ‘ignorable whitespace’).

This parameter can be combined with the ‘element-content-whitespace’ parameter to parse an XML file and return a DOM tree containing no superfluous whitespace nodes whatsoever, which can make subsequent processing much simpler:

parser= dom.createLSParser(dom.MODE_SYNCHRONOUS, None)
parser.domConfig.setParameter('element-content-whitespace', 0)
parser.domConfig.setParameter('pxdom-assume-element-content', 1)
doc= parser.parse('file:///data/foo.xml')

Extra object properties

Node.pxdomLocation

Read-only property giving a DOM Level 3 DOMLocator object for any Node.

Node.pxdomContent

A convenience property to get the markup for a node, or replace the node with alternative parsed markup, without having to create a separate LSSerializer or LSParser.

All nodes have a readable pxdomContent, but only those at content level are writable (attribute nodes, for instance, are not). The document’s domConfig is used to give parameters for parse and serialise operations invoked by pxdomContent.

pxdomContent is an extended replacement for the ElementLS.markupContent property that was in earlier Working Drafts of the DOM 3 LS spec.

Entity.pxdomAvailable

A flag indicating whether the entity’s replacement content is available in the childNodes property. Internal entities are always available; unparsed external entities never are; for parsed external entities it depends on whether external resources were resolved at parse-time.

Entity.pxdomDocumentURI

On external entities, gives the actual URI the entity was read from, after applying the systemId to the baseURI and going through any LSResourceResolver redirection. For internal and unavailable entities this property is null.

DocumentType.pxdomElements/Attlists

In addition to entities and notations, pxdom includes NamedNodeMaps in the DocumentType for the other two types of declaration that might occur in the DTD. They can be read to get more information on content models than the DOM Level 3 TypeInfo interface makes available.

Extra pxdom node types

ElementDeclaration

ElementDeclarations can be obtained from the DocumentType.pxdomElements map. Its nodeName is the element name given in the corresponding DTD <!ELEMENT> declaration).

ElementDeclaration nodes have an integer contentType property with enum keys EMPTY_CONTENT, ANY_CONTENT, MIXED_CONTENT and ELEMENT_CONTENT. In the case of mixed and element content, the elements property gives more information on the child elements allowed.

AttributeDeclarationList

AttributeDeclarationLists can be obtained from the DocumentType.pxdomAttlists map. Its nodeName is the name of the element whose attributes it is defining, as given in the <!ATTLIST> declaration).

AttributeListDeclarations hold a NamedNodeMap in their declarations property, mapping attribute names from the declaration to corresponding AttributeDeclaration nodes.

AttributeDeclaration

AttributeDeclaration nodes have an integer attributeType property with enum keys ID_ATTR, IDREF_ATTR, IDREFS_ATTR, ENTITY_ATTR, ENTITIES_ATTR, NMTOKEN_ATTR, NMTOKENS_ATTR, NOTATION_ATTR, CDATA_ATTR and ENUMERATION_ATTR.

In the case of enumeration and notation attribute types, the typeValues property holds a list of possible string values. There is also an integer defaultType property with enum keys REQUIRED_VALUE, IMPLIED_VALUE, DEFAULT_VALUE and FIXED_VALUE. In the case of fixed and defaulting attributes, the childNodes property holds any text and/or entity reference nodes that make up the default value.

Changelog

Updates from 1.0 to 1.1

Updates from 0.9 to 1.0

Updates from 0.8 to 0.9

Updates from 0.7 to 0.8

Updates from 0.6 to 0.7

Future work

Thanks are due to all who contributed comments on previous releases, as well as all responsible for the DOM Test Suite (which has caught many gotchas in previous pxdom versions, regardless of the bugs I keep filing against it), particularly Curt Arnold (for fixing many of them).

Licence (new-BSD-style)

Copyright © 2004, Andrew Clover. All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

This software is provided by the copyright holder and contributors “as is” and any express or implied warranties, including, but not limited to, the implied warranties of merchantability and fitness for a particular purpose are disclaimed. In no event shall the copyright owner or contributors be liable for any direct, indirect, incidental, special, exemplary, or consequential damages (including, but not limited to, procurement of substitute goods or services; loss of use, data, or profits; or business interruption) however caused and on any theory of liability, whether in contract, strict liability, or tort (including negligence or otherwise) arising in any way out of the use of this software, even if advised of the possibility of such damage.