From dlichteblau at common-lisp.net Tue May 1 18:21:41 2007
From: dlichteblau at common-lisp.net (dlichteblau)
Date: Tue, 1 May 2007 14:21:41 -0400 (EDT)
Subject: [cxml-cvs] CVS cxml/doc
Message-ID: <20070501182141.C351172085@common-lisp.net>
Update of /project/cxml/cvsroot/cxml/doc
In directory clnet:/tmp/cvs-serv20218/doc
Modified Files:
cxml.css html.xsl index.xml quickstart.xml
Log Message:
klacks:get-attribute; dribbling source fix; FAQ
--- /project/cxml/cvsroot/cxml/doc/cxml.css 2007/04/22 13:23:54 1.7
+++ /project/cxml/cvsroot/cxml/doc/cxml.css 2007/05/01 18:21:40 1.8
@@ -63,10 +63,15 @@
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;
--- /project/cxml/cvsroot/cxml/doc/html.xsl 2007/03/04 21:04:11 1.4
+++ /project/cxml/cvsroot/cxml/doc/html.xsl 2007/05/01 18:21:40 1.5
@@ -4,11 +4,11 @@
doctype-public="-//W3C//DTD HTML 4.01 Transitional//EN"
doctype-system="http://www.w3.org/TR/html4/loose.dtd"/>
-
+
+
+
+
+ Relax NG validation is available as a separate + project: cxml-rng. +
+ + -rel-2007-xx-yy
Make sure to install and load cxml first.
-Create a test file called example.xml:
++ To try the following examples, create a test file + called example.xml: +
* (with-open-file (s "example.xml" :direction :output) (write-string "<test a='b'><child/></test>" s))+
Parse example.xml into a DOM tree (read more):
* (cxml:parse-file "example.xml" (cxml-dom:make-dom-builder)) #<DOM-IMPL::DOCUMENT @ #x72206172> + ;; save result for later: * (defparameter *example* *) *EXAMPLE*+
Inspect the DOM tree (read more):
* (dom:document-element *example*) #<DOM-IMPL::ELEMENT test @ #x722b6ba2> -* (dom:tag-name (dom:document-element *example*)) + +* (dom:tag-name (dom:document-element *example*)) "test" -* (dom:child-nodes (dom:document-element *example*)) + +* (dom:child-nodes (dom:document-element *example*)) #(#<DOM-IMPL::ELEMENT child @ #x722b6d8a>) -* (dom:get-attribute (dom:document-element *example*) "a") + +* (dom:get-attribute (dom:document-element *example*) "a") "b"+
Serialize the DOM document back into a file (read more):
-(with-open-file (out "example.out" :direction :output :element-type '(unsigned-byte 8)) - (dom:map-document (cxml:make-octet-stream-sink out) *example*))+
(with-open-file (out "example.out" :direction :output :element-type '(unsigned-byte 8)) + (dom:map-document (cxml:make-octet-stream-sink out) *example*)+ +
+ 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. +
As an alternative to DOM, parse into xmls-compatible list structure (read more):
* (cxml:parse-file "example.xml" (cxml-xmls:make-xmls-builder)) ("test" (("a" "b")) ("child" NIL))+
+ 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 cxml-xmls:map-node. +
+ +* (with-open-file (out "example.out" :direction :output :element-type '(unsigned-byte 8)) + (cxml-xmls:map-node (cxml:make-octet-stream-sink out) + '("test" (("a" "b")) ("child" nil))))+ +
Use klacks to read events from the parser incrementally. The following example looks only for :start-element and :end-element events and prints them (read more):
* (klacks:with-open-source - (s (cxml:make-source #p"example.xml")) + (s (cxml:make-source #p"example.xml")) (loop - for key = (klacks:peek s) + for key = (klacks:peek s) while key do (case key (:start-element - (format t "~A {" (klacks:current-qname s))) + (format t "~A {" (klacks:current-qname s))) (:end-element (format t "}"))) - (klacks:consume s))) + (klacks:consume s))) test {child {}}+ +
+ Serialization is always done using sinks, which accept SAX events, + but there are convenience functions and macros to make that easier + to use: +
+(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.")))+
+ Prints this to stream: +
+<foo xyz="abc"> + <bar blub="bla"></bar> + Hi there. +</foo>+ +
+ 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. +
+ ++ The are several solutions to this, covered in detail below: +
+ Here are the example files for the following solutions to this + problem: +
+ + + dtdexample.xml: +<!DOCTYPE test SYSTEM 'http://www.lichteblau.com/blubba/dtdexample.dtd'> +<test a='b'>blub<child/></test>+ + + dtdexample.dtd: +
<!ELEMENT test (#PCDATA|child)*> +<!ATTLIST test + a CDATA #REQUIRED + > + +<!ELEMENT child EMPTY> ++ +
+ Use the :entity-resolver argument to parse-file to + specify a function that maps System IDs and Public IDs to local + files of your choice: +
+ +(let ((uri "http://www.lichteblau.com/blubba/dtdexample.dtd") + (pathname "dtdexample.dtd")) + (flet ((resolver (pubid sysid) + (declare (ignore pubid)) + (when (puri:uri= sysid (puri:parse-uri uri)) + (open pathname :element-type '(unsigned-byte 8))))) + (cxml:parse-file "dtdexample.xml" (cxml-dom:make-dom-builder) :entity-resolver #'resolver)))+ + +
+ Yes and no. +
++ Yes, you can force CXML to do this, see the following example. +
+ ++ 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. +
+ ++ The trick to make CXML skip the DTD is to pretend that it is empty + by returning a zero-length stream instead: +
+ +(flet ((resolver (pubid sysid) + (declare (ignore pubid sysid)) + (flexi-streams:make-in-memory-input-stream nil))) + (cxml:parse-file "dtdexample.xml" (cxml-dom:make-dom-builder) :entity-resolver #'resolver))+ +
+ Rather than writing an entity resolver function yourself, CXML can + use XML catalogs to find DTDs and entity files on your local system. +
++ 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. +
+By default, CXML looks for the catalog in /etc/xml/catalog + (Linux) and /usr/local/share/xml/catalog.ports (FreeBSD). +
+* (setf cxml:*catalog* (cxml:make-catalog)) +* (cxml:parse-file "test.xhtml" (cxml-dom:make-dom-builder))+ +
+ Sure, just use an entity-resolver function that does it. +
++ Install Drakma and try this: +
+(flet ((resolver (pubid sysid) + (declare (ignore pubid)) + (when (eq (puri:uri-scheme sysid) :http) + (drakma:http-request sysid :want-stream t)))) + (cxml:parse-file "dtdexample.xml" (cxml-dom:make-dom-builder) :entity-resolver #'resolver))
Relax NG validation is available as a separate - project: cxml-rng. + project: cxml-rng.
rel-2007-xx-yy
+rel-2007-05-26
rel-2007-02-18
$ ln -sf `pwd`/cxml.asd /path/to/your/registry/+
$ ln -sf `pwd`/cxml.asd /path/to/your/registry/ +$ ln -sf `pwd`/runes.asd /path/to/your/registry/
Then compile CXML using:
* (asdf:operate 'asdf:load-op :cxml)From dlichteblau at common-lisp.net Sat May 26 21:55:59 2007 From: dlichteblau at common-lisp.net (dlichteblau) Date: Sat, 26 May 2007 17:55:59 -0400 (EDT) Subject: [cxml-cvs] CVS cxml/runes Message-ID: <20070526215559.0678D360E2@common-lisp.net> Update of /project/cxml/cvsroot/cxml/runes In directory clnet:/tmp/cvs-serv28676/runes Modified Files: utf8.lisp Log Message: runes.asd neues release --- /project/cxml/cvsroot/cxml/runes/utf8.lisp 2005/12/27 20:01:16 1.2 +++ /project/cxml/cvsroot/cxml/runes/utf8.lisp 2007/05/26 21:55:58 1.3 @@ -29,7 +29,7 @@ (defun rod-reader (stream subchar arg) (runes::rod-string (runes::rod-reader stream subchar arg))) -(setf cxml-system::*utf8-runes-readtable* +(setf runes-system:*utf8-runes-readtable* (let ((rt (copy-readtable))) (set-dispatch-macro-character #\# #\/ 'rune-reader rt) (set-dispatch-macro-character #\# #\" 'rod-reader rt) From dlichteblau at common-lisp.net Sat May 26 22:05:14 2007 From: dlichteblau at common-lisp.net (dlichteblau) Date: Sat, 26 May 2007 18:05:14 -0400 (EDT) Subject: [cxml-cvs] CVS cxml Message-ID: <20070526220514.2AF01662D6@common-lisp.net> Update of /project/cxml/cvsroot/cxml In directory clnet:/tmp/cvs-serv31965 Added Files: runes.asd Log Message: runes.asd --- /project/cxml/cvsroot/cxml/runes.asd 2007/05/26 22:05:14 NONE +++ /project/cxml/cvsroot/cxml/runes.asd 2007/05/26 22:05:14 1.1 ;;; XXX Die vielen verschiedenen Systeme hier sollten vielleicht ;;; Module eines grossen Systems CXML werden? (defpackage :runes-system (:use :asdf :cl) (:export #:*utf8-runes-readtable*)) (in-package :runes-system) (defvar *utf8-runes-readtable*) (defclass closure-source-file (cl-source-file) ()) #+sbcl (defmethod perform :around ((o compile-op) (s closure-source-file)) ;; shut up already. Correctness first. (handler-bind ((sb-ext:compiler-note #'muffle-warning)) (let (#+sbcl (*compile-print* nil)) (call-next-method)))) #-(or rune-is-character rune-is-integer) (progn (format t "~&;;; Checking for wide character support...") (force-output) (pushnew (dotimes (x 65536 (progn (format t " ok, characters have at least 16 bits.~%") :rune-is-character)) (unless (and (< x char-code-limit) (code-char x)) (format t " no, reverting to octet strings.~%") (return :rune-is-integer))) *features*)) #-rune-is-character (format t "~&;;; Building Closure with (UNSIGNED-BYTE 16) RUNES~%") #+rune-is-character (format t "~&;;; Building Closure with CHARACTER RUNES~%") (defsystem :runes :default-component-class closure-source-file :pathname (merge-pathnames "runes/" (make-pathname :name nil :type nil :defaults *load-truename*)) :serial t :components ((:file "package") (:file "definline") (:file runes :pathname #-rune-is-character "runes" #+rune-is-character "characters") #+rune-is-integer (:file "utf8") (:file "syntax") (:file "encodings") (:file "encodings-data") (:file "xstream") (:file "ystream")))