CXML W3C DOM

# W3C DOM

CXML implements the DOM Level 2 Core interfaces. For details on DOM, please refer to the specification.

### Parsing into DOM

To parse an XML document into a DOM tree, use the SAX parser with a DOM builder as the SAX handler. Example:

    (cxml:parse-file "test.xml" (cxml-dom:make-dom-builder))

Function CXML-DOM:MAKE-DOM-BUILDER () Create a SAX handler which builds a DOM document.

This functions returns a DOM builder that will work with the default configuration of the SAX parser and is guaranteed to use characters/strings instead of runes/rods, if that makes a difference on the Lisp in question.

This is the same as rune-dom:make-dom-builder on Lisps with Unicode support, and the same as utf8-dom:make-dom-builder otherwise.

Function RUNE-DOM:MAKE-DOM-BUILDER () Create a SAX handler which builds a DOM document using runes and rods.

Function UTF8-DOM:MAKE-DOM-BUILDER () (Only on Lisps without Unicode support:) Create a SAX handler which builds a DOM document using UTF-8-encoded strings.

### Serializing DOM

To serialize a DOM document, use a SAX serialization sink as the argument to dom:map-document, which generates SAX events for the DOM tree.

Applications dealing with namespaces might want to inject a namespace normalizer into the sink chain.

Function DOM:MAP-DOCUMENT (handler document &key include-xmlns-attributes include-default-values include-doctype) Traverse a DOM document and call SAX functions as if an XML representation of the document was processed by a SAX parser.

Keyword arguments:

- include-xmlns-attributes -- defaults to sax:*include-xmlns-attributes*
- include-doctype -- One of nil (no doctype declaration), :full-internal-subset (include a doctype declaration and the full internal subset), or :canonical-notations (write a doctype declaration with an internal subset including only notations, as required for canonical serialization).
- include-default-values -- include attribute nodes with nil dom:specified.
- recode -- (ignored on Lisps with Unicode support.) If true, recode UTF-8 strings to rods. Defaults to true if used with a UTF-8 DOM document. It can be set to false manually to suppress recoding in this case.

### DOM/Lisp mapping

Note that there is no "standard" DOM mapping for Lisp.

DOM is specified in CORBA IDL, but it refrains from using object-oriented IDL features, allowing for a much more natural Lisp implemenation than the the ordinary IDL/Lisp mapping would. Differences between CXML's DOM and the direct IDL/Lisp mapping:

- DOM function names are symbols in the DOM package (not the OP package).
- DOM functions have proper required arguments, not a huge &rest lambda list.
- Although most IDL interfaces are implemented as CLOS classes by CXML, the Lisp types of DOM objects is not documented and cannot be relied upon. A node's type can be determined using dom:node-type instead.
- DOMString is mapped to rod, which is either an (unsigned-byte 16) array type or a string type.
- The IDL/Lisp mapping maps CORBA enums to Lisp keywords. Unfortunately, the DOM IDL does not use enums. Instead, both exception types and node types are defined integer constants. CXML chooses to ignore this definition and uses keywords instead.
- DOM uses StudlyCaps. Lisp programmers don't. We insert #\- before every upper case letter preceded by a lower case letter and before every upper case letter which is followed by a lower case letter, but preceded by a capital letter. This algorithms leads to the natural Lisp spelling of DOM function names.
- Implementation note: DOM's NodeList does not necessarily map to a native "sequence" type. (For example, node lists are objects in Java, not arrays.) NodeList is specified to reflect changes done after a node list was created, so node lists cannot be Lisp lists. (A node list could be implemented as a CLOS object pointing to said list though.) Instead, CXML currently implements node lists as adjustable vectors. Note that code which relies on this implementation and uses Lisp sequence functions instead of sticking to dom:item and dom:length is not portable. As a compromise, you can use our extensions dom:map-node-list or dom:do-node-list, which can be implemented portably.