STP examples

The following simple examples and code snippets have been taken from the STP tutorial. The containing tutorial slide is linked from each example.

(Page 2)  To parse into STP, use an STP builder together with a function generating SAX events:
(cxml:parse #p"example.xml" (stp:make-builder))
(Page 2)  Serialize STP by sending SAX events for the tree to a sink:
(stp:serialize * (cxml:make-character-stream-sink *standard-output*))
(Page 7)  getElementsByTagNameNS("foo", "")
(stp:filter-recursively (stp:of-name "foo") node)
(Page 10)  Making an element (no namespace)
CL-USER> (stp:make-element "list")
#.(STP:ELEMENT :LOCAL-NAME "list")
(Page 10)  Making an element (with namespace)
CL-USER> (stp:make-element "z:list" "http://namespace")
#.(STP:ELEMENT
   :LOCAL-NAME "list"
   :NAMESPACE-PREFIX "z"
   :NAMESPACE-URI "http://namespace")
(defun attribute-value (element name &optional uri) ...)
(defun (setf attribute-value) (newval element name &optional uri) ...)
(Page 13)  with-attributes
(let ((e (stp:document-element
	  (cxml:parse "<foo a='quux'/>" (stp:make-builder)))))
  (stp:with-attributes ((a "a") (b "x:b" "http://foo")) e
    (setf b (concatenate 'string ".oO(" a ")"))
    e))
#.(CXML-STP:ELEMENT
   :ATTRIBUTES '(#.(CXML-STP:ATTRIBUTE
                    :VALUE ".oO(quux)"
                    :LOCAL-NAME "b"
                    :NAMESPACE-PREFIX "x"
                    :NAMESPACE-URI "http://foo")
                 #.(CXML-STP:ATTRIBUTE
                    :VALUE "1"
                    :LOCAL-NAME "a"))
   :LOCAL-NAME "foo")
(Page 14)  Making an attribute node
CL-USER> (stp:make-attribute "123"
                             "a:defaultValue"
                             "http://relaxng.org/ns/compatibility/annotations/1.0")
#.(STP:ATTRIBUTE
   :VALUE "123"
   :LOCAL-NAME "defaultValue"
   :NAMESPACE-PREFIX "a"
   :NAMESPACE-URI "http://relaxng.org/ns/compatibility/annotations/1.0")
(Page 14)  Making an attribute node (without namespace)
CL-USER> (stp:make-attribute "123" "defaultValue")
#.(STP:ATTRIBUTE
   :VALUE "123"
   :LOCAL-NAME "defaultValue">
(Page 15)  Namespaces are declared implicitly
<element xmlns="http://relaxng.org/ns/structure/1.0"
	 xmlns:foo="http://foo"
	 name="foo"
	 foo:annotation="bar">
  <empty/>
</element>
#.(STP:ELEMENT
   :LOCAL-NAME "element"
   :NAMESPACE-URI "http://relaxng.org/ns/structure/1.0"
   :ATTRIBUTES '(#.(STP:ATTRIBUTE
                    :LOCAL-NAME "name"
                    :VALUE "foo")
                 #.(STP:ATTRIBUTE
                    :LOCAL-NAME "annotation"
                    :NAMESPACE-PREFIX "foo"
                    :NAMESPACE-URI "http://foo"
                    :VALUE "bar"))
   :CHILDREN ... uninteresting child nodes elided ...)
(Page 16)  Well-formed namespaces
(let ((e (stp:make-element           "a:foo" "http://a"))
      (a (stp:make-attribute "value" "b:bar" "http://b")))
  (stp:add-attribute e a))
Okay
(Page 16)  Namespaces not well-formed
(let ((e (stp:make-element           "a:foo" "http://a"))
      (a (stp:make-attribute "value" "a:bar" "http://b")))
  (stp:add-attribute e a))
Error: namespace collision with element
(Page 19)  Text nodes
CL-USER> (stp:make-text "chit-chat")
#.(STP:TEXT :DATA "chit-chat")
(Page 19)  Comment nodes
CL-USER> (stp:make-comment "Ich bin ein Blindtext.")
#.(STP:COMMENT :DATA "Ich bin ein Blindtext.")
(Page 19)  Processing instruction nodes
<?xml-stylesheet type='text/xsl' href='style.xsl'?>
CL-USER> (stp:make-processing-instruction "xml-stylesheet" "type='text/xsl' href='style.xsl'")
#.(STP:PROCESSING-INSTRUCTION
   :DATA "type='text/xsl' href='style.xsl'"
   :TARGET "xml-stylesheet")
(Page 21)  Not all strings are allowed as comments
CL-USER> (stp:make-comment "verboten: --")
Error: forbidden -- in comment
(Page 21)  Names must follow the XML grammar
CL-USER> (stp:make-element "1eadingdigit")
Error: not an NCName: 1eadingdigit
(Page 21)  Mild protection against bogus argument order
CL-USER> (stp:make-element "html" "oops")
WARNING: namespace URI does not look like an absolute URL: "oops"
(Page 21)  The XMLDecl is not a processing instruction
CL-USER> (stp:make-processing-instruction "xml" "version='1.0'")
Error: attempt to pretend that a PI is an XMLDecl
(Page 22)  Convert STP to DOM
CL-USER> (stp:serialize document (cxml-dom:make-dom-builder))
#<RUNE-DOM::DOCUMENT {1005A421F1}>
(Page 22)  Convert STP to DOM
CL-USER> (stp:serialize document (cxml-xmls:make-xmls-builder))
(("x" . "") NIL)
(Page 22)  Validate against Relax NG schema
CL-USER> (let ((schema (cxml-rng:parse-compact #p"/home/david/demo.rnc")))
	   (stp:serialize document (cxml-rng:make-validator schema)))
Error: element example () not valid,
was expecting an element named "demo", in the namespace ""
   [Condition of type CXML-RNG:RNG-ERROR]