klacks:get-attribute; dribbling source fix; FAQ
This commit is contained in:
@ -63,10 +63,15 @@ body {
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
|
||||
h1,h2,h3 {
|
||||
h1 {
|
||||
margin-left: -30px;
|
||||
}
|
||||
|
||||
h2,h3 {
|
||||
margin-left: -30px;
|
||||
margin-top: 2em;
|
||||
}
|
||||
|
||||
pre {
|
||||
background-color: #eeeeee;
|
||||
border: solid 1px #d0d0d0;
|
||||
|
||||
34
doc/html.xsl
34
doc/html.xsl
@ -4,11 +4,11 @@
|
||||
doctype-public="-//W3C//DTD HTML 4.01 Transitional//EN"
|
||||
doctype-system="http://www.w3.org/TR/html4/loose.dtd"/>
|
||||
|
||||
<xsl:template match="@*|node()">
|
||||
<xsl:copy>
|
||||
<xsl:apply-templates select="@*|node()"/>
|
||||
</xsl:copy>
|
||||
</xsl:template>
|
||||
<xsl:template match="@*|node()">
|
||||
<xsl:copy>
|
||||
<xsl:apply-templates select="@*|node()"/>
|
||||
</xsl:copy>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="documentation">
|
||||
<html>
|
||||
@ -38,7 +38,7 @@
|
||||
<li>
|
||||
<ul class="hack">
|
||||
<li>
|
||||
<a href="quickstart.html"><b>Quick-Start Example</b></a>
|
||||
<a href="quickstart.html"><b>Quick-Start Example / FAQ</b></a>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
@ -85,4 +85,26 @@
|
||||
</html>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="page-index">
|
||||
<ul>
|
||||
<xsl:for-each select="//heading">
|
||||
<li>
|
||||
<a href="#{generate-id()}">
|
||||
<xsl:copy>
|
||||
<xsl:apply-templates select="node()"/>
|
||||
</xsl:copy>
|
||||
</a>
|
||||
</li>
|
||||
</xsl:for-each>
|
||||
</ul>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="heading">
|
||||
<a name="{generate-id()}"/>
|
||||
<h3>
|
||||
<xsl:copy>
|
||||
<xsl:apply-templates select="node()"/>
|
||||
</xsl:copy>
|
||||
</h3>
|
||||
</xsl:template>
|
||||
</xsl:stylesheet>
|
||||
|
||||
@ -48,8 +48,15 @@
|
||||
information</a>).
|
||||
</p>
|
||||
|
||||
<h3>See also</h3>
|
||||
<p>
|
||||
Relax NG validation is available as a separate
|
||||
project: <a href="">cxml-rng</a>.
|
||||
</p>
|
||||
|
||||
|
||||
<a name="changes"/>
|
||||
<h2>Recent Changes</h2>
|
||||
<h3>Recent Changes</h3>
|
||||
<p class="nomargin"><tt>rel-2007-xx-yy</tt></p>
|
||||
<ul class="nomargin">
|
||||
<li>xml:base support (SAX and Klacks only, not yet used in DOM).
|
||||
|
||||
@ -1,56 +1,247 @@
|
||||
<documentation title="CXML Quick-Start Example">
|
||||
<h1>Quick-Start Example</h1>
|
||||
<h1>Quick-Start Example / FAQ</h1>
|
||||
|
||||
<p>
|
||||
Make sure to <a href="installation.html#installation">install and load</a> cxml first.
|
||||
</p>
|
||||
|
||||
<p>Create a test file called <tt>example.xml</tt>:</p>
|
||||
<h3>
|
||||
On this page
|
||||
</h3>
|
||||
<page-index/>
|
||||
|
||||
<p>
|
||||
To try the following examples, create a test file
|
||||
called <tt>example.xml</tt>:
|
||||
</p>
|
||||
<pre>* <b>(with-open-file (s "example.xml" :direction :output)
|
||||
(write-string "<test a='b'><child/></test>" s))</b></pre>
|
||||
|
||||
<heading>Parsing a file</heading>
|
||||
|
||||
<p>Parse <tt>example.xml</tt> into a DOM tree (<a href="sax.html#parser">read
|
||||
more</a>):</p>
|
||||
<pre>* <b>(cxml:parse-file "example.xml" (cxml-dom:make-dom-builder))</b>
|
||||
#<DOM-IMPL::DOCUMENT @ #x72206172>
|
||||
|
||||
;; save result for later:
|
||||
* <b>(defparameter *example* *)</b>
|
||||
*EXAMPLE*</pre>
|
||||
|
||||
<heading>Using DOM</heading>
|
||||
|
||||
<p>Inspect the DOM tree (<a href="sax.html#dom">read more</a>):</p>
|
||||
<pre>* <b>(dom:document-element *example*)</b>
|
||||
#<DOM-IMPL::ELEMENT test @ #x722b6ba2>
|
||||
* <b>(dom:tag-name (dom:document-element *example*))</b>
|
||||
|
||||
* (<b>dom:tag-name</b> (dom:document-element *example*))
|
||||
"test"
|
||||
* <b>(dom:child-nodes (dom:document-element *example*))</b>
|
||||
|
||||
* (<b>dom:child-nodes</b> (dom:document-element *example*))
|
||||
#(#<DOM-IMPL::ELEMENT child @ #x722b6d8a>)
|
||||
* <b>(dom:get-attribute (dom:document-element *example*) "a")</b>
|
||||
|
||||
* (<b>dom:get-attribute</b> (dom:document-element *example*) <b>"a"</b>)
|
||||
"b"</pre>
|
||||
|
||||
<heading>Serializing DOM</heading>
|
||||
|
||||
<p>Serialize the DOM document back into a file (<a
|
||||
href="sax.html#serialization">read more</a>):</p>
|
||||
<pre><b>(with-open-file (out "example.out" :direction :output :element-type '(unsigned-byte 8))
|
||||
(dom:map-document (cxml:make-octet-stream-sink out) *example*))</b></pre>
|
||||
<pre>(with-open-file (out "example.out" :direction :output :element-type '(unsigned-byte 8))
|
||||
<b>(dom:map-document (cxml:make-octet-stream-sink out) *example*)</b></pre>
|
||||
|
||||
<heading>Parsing into XMLS-like lists</heading>
|
||||
|
||||
<p>
|
||||
If DOM is not the representation you want to you, parsing into
|
||||
other data structures is possible using the same SAX parser
|
||||
function, while using a different handler.
|
||||
The XMLS builder is included for compatibility with XMLS, and also
|
||||
also sample code (see cxml/xml/xmls-compat.lisp) for your own
|
||||
handlers.
|
||||
</p>
|
||||
|
||||
<p>As an alternative to DOM, parse into xmls-compatible list
|
||||
structure (<a href="xmls-compat.html">read more</a>):</p>
|
||||
<pre>* <b>(cxml:parse-file "example.xml" (cxml-xmls:make-xmls-builder))</b>
|
||||
("test" (("a" "b")) ("child" NIL))</pre>
|
||||
|
||||
<p>
|
||||
Again, serialization into XML is done using a sink as a SAX
|
||||
handler and a data-structure specific function to generate SAX
|
||||
events for the document, in this case <tt>cxml-xmls:map-node</tt>.
|
||||
</p>
|
||||
|
||||
<pre>* (with-open-file (out "example.out" :direction :output :element-type '(unsigned-byte 8))
|
||||
(<b>cxml-xmls:map-node (cxml:make-octet-stream-sink out)
|
||||
'("test" (("a" "b")) ("child" nil)))</b>)</pre>
|
||||
|
||||
<heading>Parsing incrementally using Klacks</heading>
|
||||
|
||||
<p>Use klacks to read events from the parser incrementally. The
|
||||
following example looks only for :start-element and :end-element
|
||||
events and prints them (<a href="klacks.html">read more</a>):</p>
|
||||
<pre>* <b>(klacks:with-open-source
|
||||
(s (cxml:make-source #p"example.xml"))
|
||||
(s (cxml:make-source #p"example.xml"))</b>
|
||||
(loop
|
||||
for key = (klacks:peek s)
|
||||
for key = <b>(klacks:peek s)</b>
|
||||
while key
|
||||
do
|
||||
(case key
|
||||
(:start-element
|
||||
(format t "~A {" (klacks:current-qname s)))
|
||||
(format t "~A {" <b>(klacks:current-qname s)</b>))
|
||||
(:end-element
|
||||
(format t "}")))
|
||||
(klacks:consume s)))</b>
|
||||
<b>(klacks:consume s)</b>))
|
||||
test {child {}}</pre>
|
||||
|
||||
<heading>Writing XML</heading>
|
||||
|
||||
<p>
|
||||
Serialization is always done using sinks, which accept SAX events,
|
||||
but there are convenience functions and macros to make that easier
|
||||
to use:
|
||||
</p>
|
||||
<pre>(cxml:with-xml-output (cxml:make-octet-stream-sink stream :indentation 2 :canonical nil)
|
||||
(cxml:with-element "foo"
|
||||
(cxml:attribute "xyz" "abc")
|
||||
(cxml:with-element "bar"
|
||||
(cxml:attribute "blub" "bla"))
|
||||
(cxml:text "Hi there.")))</pre>
|
||||
<p>
|
||||
Prints this to <tt>stream</tt>:
|
||||
</p>
|
||||
<pre><foo xyz="abc">
|
||||
<bar blub="bla"></bar>
|
||||
Hi there.
|
||||
</foo></pre>
|
||||
|
||||
<heading>Help! CXML says 'URI scheme :HTTP not supported'</heading>
|
||||
|
||||
<p>
|
||||
By default, this error will occur when the DTD (or generally, any
|
||||
entity) has an http:// URL as its system ID. CXML itself
|
||||
understands only file:// URLs, but allows users to customize the
|
||||
behaviour for all URLs.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The are several solutions to this, covered in detail below:
|
||||
<ul>
|
||||
<li>
|
||||
Load the DTD/entity from local files using an entity resolver
|
||||
</li>
|
||||
<li>
|
||||
Skip parsing of the DTD/entity entirely by pretending it is
|
||||
empty, again using an entity resolver.
|
||||
</li>
|
||||
<li>
|
||||
Use a <em>catalog</em> to make CXML find DTDs in the local
|
||||
filesystem automatically.
|
||||
</li>
|
||||
<li>
|
||||
Teach CXML actually load DTDs using HTTP.
|
||||
</li>
|
||||
</ul>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Here are the example files for the following solutions to this
|
||||
problem:
|
||||
</p>
|
||||
|
||||
<a href="http://www.lichteblau.com/blubba/dtdexample.xml">
|
||||
<tt>dtdexample.xml</tt>:</a>
|
||||
<pre><!DOCTYPE test SYSTEM 'http://www.lichteblau.com/blubba/dtdexample.dtd'>
|
||||
<test a='b'>blub<child/></test></pre>
|
||||
|
||||
<a href="http://www.lichteblau.com/blubba/dtdexample.dtd">
|
||||
<tt>dtdexample.dtd</tt></a>:
|
||||
<pre><!ELEMENT test (#PCDATA|child)*>
|
||||
<!ATTLIST test
|
||||
a CDATA #REQUIRED
|
||||
>
|
||||
|
||||
<!ELEMENT child EMPTY>
|
||||
</pre>
|
||||
|
||||
<heading>Loading DTDs from local files</heading>
|
||||
|
||||
<p>
|
||||
Use the :entity-resolver argument to <tt>parse-file</tt> to
|
||||
specify a function that maps System IDs and Public IDs to local
|
||||
files of your choice:
|
||||
</p>
|
||||
|
||||
<pre>(let ((uri "http://www.lichteblau.com/blubba/dtdexample.dtd")
|
||||
(pathname "dtdexample.dtd"))
|
||||
(flet ((resolver (pubid sysid)
|
||||
(declare (ignore pubid))
|
||||
<b>(when (puri:uri= sysid (puri:parse-uri uri))
|
||||
(open pathname :element-type '(unsigned-byte 8)))</b>))
|
||||
(cxml:parse-file "dtdexample.xml" (cxml-dom:make-dom-builder) <b>:entity-resolver #'resolver</b>)))</pre>
|
||||
|
||||
|
||||
<heading>Can I skip loading of DTDs entirely?</heading>
|
||||
|
||||
<p>
|
||||
Yes and no.
|
||||
</p>
|
||||
<p>
|
||||
<i>Yes</i>, you can force CXML to do this, see the following example.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
But no, skipping the DTD will not actually work if the document
|
||||
references entities declared in the DTD, especially since neither
|
||||
SAX nor DOM are able to report unresolved entity references in
|
||||
attributes.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The trick to make CXML skip the DTD is to pretend that it is empty
|
||||
by returning a zero-length stream instead:
|
||||
</p>
|
||||
|
||||
<pre>(flet ((resolver (pubid sysid)
|
||||
(declare (ignore pubid sysid))
|
||||
<b>(flexi-streams:make-in-memory-input-stream nil)</b>))
|
||||
(cxml:parse-file "dtdexample.xml" (cxml-dom:make-dom-builder) <b>:entity-resolver #'resolver</b>))</pre>
|
||||
|
||||
<heading>
|
||||
Catalogs: How can I use the HTML DTD installed by my distribution?
|
||||
</heading>
|
||||
|
||||
<p>
|
||||
Rather than writing an entity resolver function yourself, CXML can
|
||||
use XML catalogs to find DTDs and entity files on your local system.
|
||||
</p>
|
||||
<p>
|
||||
Catalogs are particularly helpful for DTDs that are
|
||||
pre-installed. For example, most Linux distributions include a
|
||||
package for the XHTML DTD. The DTD will reside in a
|
||||
distribution-dependent location, which the central catalog file
|
||||
points to.
|
||||
</p>
|
||||
<p>By default, CXML looks for the catalog in /etc/xml/catalog
|
||||
(Linux) and /usr/local/share/xml/catalog.ports (FreeBSD).
|
||||
</p>
|
||||
<pre>* <b>(setf cxml:*catalog* (cxml:make-catalog))</b>
|
||||
* (cxml:parse-file "test.xhtml" (cxml-dom:make-dom-builder))</pre>
|
||||
|
||||
<heading>
|
||||
Can I load DTDs through HTTP?
|
||||
</heading>
|
||||
|
||||
<p>
|
||||
Sure, just use an entity-resolver function that does it.
|
||||
</p>
|
||||
<p>
|
||||
Install <a href="http://weitz.de/drakma/">Drakma</a> and try this:
|
||||
</p>
|
||||
<pre>(flet ((resolver (pubid sysid)
|
||||
(declare (ignore pubid))
|
||||
<b>(when (eq (puri:uri-scheme sysid) :http)
|
||||
(drakma:http-request sysid :want-stream t))</b>))
|
||||
(cxml:parse-file "dtdexample.xml" (cxml-dom:make-dom-builder) <b>:entity-resolver #'resolver</b>))</pre>
|
||||
</documentation>
|
||||
|
||||
Reference in New Issue
Block a user