1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119
|
<documentation title="CXML XMLS Compatibility">
<h1>XMLS Builder</h1>
<p>
Like other XML parsers written in Lisp, CXML can work with
documents represented as list structures. The specific model
implemented by cxml is compatible with the <a
href="http://common-lisp.net/project/xmls/">xmls parser</a>. Xmls
list structures are a simpler and faster alternative to full DOM
document trees. They also serve as an example showing how to
implement user-defined document models as an independent layer
over the the base parser (c.f. <tt>xml/xmls-compat.lisp</tt> in
the cxml distribution). However, note that the list structures do
not include all information available in DOM documents
(notably, things like <tt>dom:parent-node</tt>) and are
sometimes more difficult to work with because of that since many
DOM functions cannot be implemented on them.
</p>
<p>
<b>New namespace handling:</b>
XMLS compatibility is not <i>bug-for-bug</i>-compatible with
XMLS any more. There is now a mode using pairs of local name
and namespace URI, and a second mode using qualified names
only. The old behaviour using pairs of prefix and local names
was removed.
</p>
<!--
<p>
<strike>
fixme: It is unclear to me how namespaces are meant to
work in xmls, since xmls documentation differs from how xmls
actually works in current releases. Usually applications need to
know both the namespace prefix <em>and</em> the namespace URI. We
currently follow the xmls <em>implementation</em> and use the
namespace prefix instead of following its <em>documentation</em> which
shows the URI. We do not follow xmls in munging xmlns attribute
values. Attributes themselves have namespaces and it is not clear
to me how that works in xmls.
</strike>
</p>
-->
<p>
<div class="def">Function CXML-XMLS:MAKE-XMLS-BUILDER (&key include-default-values include-namespace-uri)</div>
Create a SAX handler which builds XMLS list structures. 
If <tt>include-default-values</tt> is true, default values for
attributes declared in a DTD are included as attributes in the
xmls output. <tt>include-default-values</tt> is true by default
and can be set to <tt>nil</tt> to suppress inclusion of default
values.
</p>
<p>
If <tt>include-namespace-uri</tt> is true (the default), node
names and attribute names are pairs of local name and namespace
URI. (Except for attributes without a namespace, which are named
using a string.) Otherwise, nodes and attributes are named by
their qualified name.
</p>
<p>
Example:
</p>
<pre>(cxml:parse-file "test.xml" (cxml-xmls:make-xmls-builder))</pre>
<p>
<div class="def">Function CXML-XMLS:MAP-NODE (handler node &key include-xmlns-attributes include-namespace-uri)</div>
Traverse an XMLS document/node and call SAX functions as if an XML
representation of the document were processed by a SAX parser.
</p>
<p>
Use this function to serialize XMLS data. For example, we could
define a replacement for <tt>xmls:write-xml</tt> like this:
</p>
<pre>(defun write-xml (stream node &key indent)
(let ((sink (cxml:make-character-stream-sink
stream :canonical nil :indentation indent)))
(cxml-xmls:map-node sink node)))</pre>
<p>
<div class="def">Function CXML-XMLS:MAKE-NODE (&key name ns attrs
children) => xmls node</div>
Build a list node of the form
(<em>name</em> ((<em>name</em> <em>value</em>)<em>*</em>) <em>child*</em>).
</p>
<p>
The node list's <tt>car</tt> can also be a cons of local <tt>name</tt>
and namespace prefix <tt>ns</tt>.
</p>
<p>
<div class="def">Accessor CXML-XMLS:NODE-NAME (node)</div>
<div class="def">Accessor CXML-XMLS:NODE-NS (node)</div>
<div class="def">Accessor CXML-XMLS:NODE-ATTRS (node)</div>
<div class="def">Accessor CXML-XMLS:NODE-CHILDREN (node)</div>
Accessors for xmls node data.
</p>
<p>
<div class="def">Accessor CXML-XMLS:MAKE-XPATH-NAVIGATOR ()</div>
Creates a navigator object for use with Plexippus XPath.
</p>
<p>
Note that the navigator object caches parts of the document
structure, so when re-using a navigator across XPath evalutions,
make sure not to modify the list structure.
</p>
<p>
Example:
</p>
<pre>CL-USER> (defparameter *test-document*
(cxml:parse
"<foo a='b'>
<a id='1'/> <b id='2'/> <c id='3'/>
<a id='4'/> <b id='5'/> <c id='6'/>
<a id='7'/> <b id='8'/> <c id='9'/>
<last/>
</foo>"
(cxml-xmls:make-xmls-builder)))
*TEST-DOCUMENT*</pre>
<pre>CL-USER> (let ((xpath:*navigator* (cxml-xmls:make-xpath-navigator)))
(xpath:evaluate "//c[position()=2]|//a[@id='1']"
*test-document*))
#<XPATH:NODE-SET (a ((id 1))), ... {27C751F1}></pre>
<pre>CL-USER> (xpath:all-nodes *)
(("a" (("id" "1"))) ("c" (("id" "6"))))</pre>
</documentation>
|