[s-xml-cvs] CVS update: s-xml/src/xml.lisp

Sven Van Caekenberghe scaekenberghe at common-lisp.net
Sun Nov 6 12:44:49 UTC 2005


Update of /project/s-xml/cvsroot/s-xml/src
In directory common-lisp.net:/tmp/cvs-serv17887/src

Modified Files:
	xml.lisp 
Log Message:
added CDATA support (patch contributed by Peter Van Eynde pvaneynd at mailworks.org)

Date: Sun Nov  6 13:44:48 2005
Author: scaekenberghe

Index: s-xml/src/xml.lisp
diff -u s-xml/src/xml.lisp:1.12 s-xml/src/xml.lisp:1.13
--- s-xml/src/xml.lisp:1.12	Thu Sep  8 17:39:29 2005
+++ s-xml/src/xml.lisp	Sun Nov  6 13:44:48 2005
@@ -1,6 +1,6 @@
 ;;;; -*- mode: lisp -*-
 ;;;;
-;;;; $Id: xml.lisp,v 1.12 2005/09/08 15:39:29 scaekenberghe Exp $
+;;;; $Id: xml.lisp,v 1.13 2005/11/06 12:44:48 scaekenberghe Exp $
 ;;;;
 ;;;; This is a Common Lisp implementation of a basic but usable XML parser.
 ;;;; The parser is non-validating and not complete (no CDATA).
@@ -446,7 +446,32 @@
   (if (char/= (read-char stream nil nil) #\>)
       (error (parser-error "expected > ending comment" nil stream))))
 
-(defun skip-special-tag (stream)
+(defun read-cdata (stream state &optional (string (make-extendable-string)))
+  "Reads in the CDATA and calls the callback for CDATA if it exists"
+  ;; we already read the <![CDATA[ stuff
+  ;; continue to read until we hit ]]>
+  (let ((char #\space)
+	(last-3-characters (list #\[ #\A #\T))
+	(pattern (list #\> #\] #\])))
+    (loop
+     (setf char (read-char stream nil nil))
+     (when (null char) (error (parser-error "encountered unexpected eof in text")))
+     (push char last-3-characters)
+     (setf (cdddr last-3-characters) nil)
+     (cond
+       ((equal last-3-characters
+	       pattern)
+	(setf (fill-pointer string)
+	      (- (fill-pointer string) 2))
+	(setf (get-seed state)
+	      (funcall (get-text-hook state)
+		       (copy-seq string)
+		       (get-seed state)))
+	(return-from read-cdata))
+       (t
+	(vector-push-extend char string))))))
+
+(defun skip-special-tag (stream state)
   "Skip an XML special tag (comments and processing instructions) in
   stream, positioned after the opening '<', unexpected eof is an error"
   ;; opening < has been read, consume ? or !
@@ -458,6 +483,15 @@
       (when (char= char #\-)
 	(skip-comment stream)
 	(return-from skip-special-tag)))
+    ;; maybe we are dealing with CDATA?
+    (when (and (char= char #\[)
+	       (loop :for pattern :across "CDATA["
+		     :for char = (read-char stream nil nil)
+		     :when (null char) :do
+		     (error (parser-error "encountered unexpected eof in cdata"))
+		     :always (char= char pattern)))
+      (read-cdata stream state (get-buffer state))
+      (return-from skip-special-tag))
     ;; loop over chars, dealing with strings (skipping their content)
     ;; and counting opening and closing < and > chars
     (let ((taglevel 1)
@@ -510,7 +544,7 @@
   (declare (special *namespaces*))
   ;; opening < has been read
   (when (char= (peek-char nil stream nil nil) #\!)
-    (skip-special-tag stream)
+    (skip-special-tag stream state)
     (return-from parse-xml-element))
   (let (char buffer open-tag parent-seed has-children)
     (setf parent-seed (get-seed state))
@@ -589,7 +623,7 @@
      (setf char (peek-char nil stream nil nil))
      (if (or (char= char #\!) (char= char #\?))
 	 ;; deal with special tags
-	 (skip-special-tag stream)
+	 (skip-special-tag stream state)
        (progn
 	 ;; read the main element
 	 (parse-xml-element stream state)




More information about the S-xml-cvs mailing list