;; @module XML ;; @author Jeff Ober , Kanen Flowers ;; @version 2.1 ;; @location http://static.artfulcode.net/newlisp/xml.lsp ;; @package http://static.artfulcode.net/newlisp/xml.qwerty ;; @description Parsing and serializing of XML data (updated for newlisp 10). ;; Functions to parse XML text (non-validating) and serialize lisp structures to XML. ;; Requires matching and newlisp 10. ;;

Version history

;; 2.1 ;; • code clean-up ;; • updated for newlisp 10 ;; • some arguments have changed in lisp->xml and xml->lisp ;; • default encoding is now determined by newlisp UTF-8 compile options ;; • added functions to trim whitespace and decode entities ;; ;; 2.0 ;; • complete rewrite ;; • added XML-compliant entities ;; • automatic serialization of data ;; ;; 1.0 ;; • initial release ;;;============================================================================ ;;; XML context ;;;============================================================================ (context 'XML) (constant 'trim-ws-re (regex-comp {(^\s*)|(\s*$)} )) (constant 'xml-entity-decode-re (regex-comp "&#(\\d{1,4});")) (constant 'xml-entity-encode-re (regex-comp (string "(" (join (map (fn (i) (format {\x%x} i)) '(34 38 39 60 62)) "|") ")"))) (constant 'default-parse-options (+ 1 16)) ;; @syntax (XML:trim-whitespace ) ;; @param a string ;;

Trims all whitespace off both ends of .

(define (trim-whitespace text) (replace trim-ws-re text "" 0x10000) text) ;; @syntax (XML:decode ) ;; @param a string ;;

Decodes XML entities and converts them to characters.

(define (decode str) (replace xml-entity-decode-re str (char (int $1)) 0x10000)) ;; @syntax (XML:encode ) ;; @param a string ;;

Encodes characters in a string to be valid for XML.

(define (encode str) (replace xml-entity-encode-re str (string "&#" (char $1) ";") 0x10000)) (define (parse-string text (options default-parse-options) , old-tags parsed) (setf old-tags (xml-type-tags)) (xml-type-tags nil nil nil nil) (setf parsed (xml-parse text options)) (apply xml-type-tags old-tags) parsed) (define (serialize-attributes attr-list) (match-let ((attrs) (@ *) attr-list) (join (map (fn (pair) (format " %s=\"%s\"" (map string pair))) attrs) ""))) (define (opening-tag node) (match-let ((tag attr _) (? ? *) node) (string "<" tag (serialize-attributes attr) ">"))) (define (closing-tag node) (string "")) (define (empty-tag node) (match-let ((tag attr _) (? ? *) node) (string "<" tag (serialize-attributes attr) " />"))) (define (serialize-text-node node) (match-let ((tag attr text) (? ? ?) node) (string (opening-tag node) (encode (decode text)) (closing-tag node)))) (define (serialize xml indent? (encoding (if utf8 "UTF-8" "ASCII")) (depth 0), buf) (setf buf "") (when (zero? depth) (write-buffer buf (string {} "\n")) (setf xml (first xml))) (when indent? (write-buffer buf (string "\n" (dup " " depth)))) (write-buffer buf (cond ((match '(? ?) xml) (empty-tag xml)) ((match '(? ? ?) xml) (serialize-text-node xml)) ((match '(? ? *) xml) (string (opening-tag xml) (join (map (fn (child) (serialize child indent? nil (+ 1 depth))) (rest (rest xml)))) (if indent? (string "\n" (dup " " depth)) "") (closing-tag xml))))) buf) ;; @syntax (XML:lisp->xml [ []]) ;; @param an SXML list ;; @param optional; whether or not to format the resulting XML (default nil) ;; @param optional; sets the encoding in the declaration ;;

Serializes an SXML list (equivalent to parsing an XML document with ;; (xml-type-tags nil nil nil nil) and options 1 and 16). The encoding in the ;; declaration defaults to UTF-8 if newlisp was compiled with UTF-8 support, ;; ASCII otherwise.

(setf lisp->xml serialize) ;; @syntax (XML:xml->lisp ) ;; @param an XML string ;;

Parses and returns an SXML list. Uses newlisp's built-in parser.

;;

Equivalent to:

;;
(begin (xml-type-tags nil nil nil) (xml-parse  (+ 1 16)))
(setf xml->lisp parse-string) (context 'MAIN)