(text xml write)

Reference

Overview

Writing XML: a node or a document, to a port or to a string.

(import (text xml) (text xml write))

(node->xml-string (xml-element (xml-name "p") Nil (list (xml-text "hi"))))
;; (Ok "<p>hi</p>")

(document->xml-string doc #:indent? #t
                      #:prefixes (list (Tuple "atom" "http://www.w3.org/2005/Atom")))

All four functions take #:indent? and #:prefixes; the document ones also #:declaration?.

Errors. XmlWriter does all the escaping. Content it cannot write is an XmlWriteError, not an exception: a character XML does not allow, U+0000 say, and three it would otherwise change or drop without a word: a comment containing -- or ending in -, a processing instruction named xml or with a target that is not a name, and processing instruction data containing ?>. Whatever was written to a port before the error stays written, and nothing says how far it got. An exception from the port itself, an IOException, passes through.

Prefixes. A name has none, so the writer chooses:

#:prefixes is the hints, as (list (Tuple "atom" "http://www.w3.org/2005/Atom")). A hinted prefix is declared once, on the root, for the namespaces the tree uses. A hint that could not be a prefix (not a name, or xml or xmlns), or that names no namespace, the xml namespace or the xmlns one, raises an ArgumentException. A prefix given twice: the first one is used, and the namespace of the second gets a generated prefix where the two meet.

Indentation. #:indent? #t puts an element’s children on lines of their own, two spaces a level, but never where the whitespace would be content: not inside an element that has text among its children, not anywhere below one, and not inside xml:space="preserve". XmlWriter’s own indentation is not used: it decides only when it meets the text, and by then has indented the elements before it.

The doctype is the one piece of markup written by hand, because XmlWriter.WriteDocType wants a C# null for an id that is not there and there is no null to give it. Its parts are checked instead of escaped: the name has to be an XML name, a public id needs a system id with it, and a system id cannot hold both kinds of quote. Its internal subset is not kept by the reader, so it is not written back.

See also: node->xml-string, document->xml-string, XmlWriteError

Reference

Types

Functions

Types

XmlWriteError

record

Content the writer cannot write, and why.

message
What is wrong.

->str answers the message.

See also: node->xml, document->xml

Functions

node->xml

function

(: node->xml (-> Node TextOutputPort (#:indent? bool) (#:prefixes (List (Tuple string string))) (Result XmlWriteError Unit)))
(node->xml node port #:indent? #f #:prefixes Nil)

Writes a node as XML to a port.

node
The node: an element, a text, a comment or a processing instruction.
port
Where to write it. It is left open.
#:indent?
Whether to put an element's children on lines of their own.
#:prefixes
Prefixes to use, as (Tuple prefix uri).
returns
Ok, or the XmlWriteError for what could not be written. What was written before it stays written.
raises ArgumentException
When a hint in #:prefixes could not be a prefix, or names no namespace, the xml one or the xmlns one.

See also: node->xml-string, document->xml

node->xml-string

function

(: node->xml-string (-> Node (#:indent? bool) (#:prefixes (List (Tuple string string))) (Result XmlWriteError string)))
(node->xml-string node #:indent? #f #:prefixes Nil)

A node as a string of XML.

node
The node.
#:indent?
Whether to put an element's children on lines of their own.
#:prefixes
Prefixes to use, as (Tuple prefix uri).
returns
The XML, or the XmlWriteError for what could not be written.
raises ArgumentException
When a hint in #:prefixes could not be a prefix, or names no namespace, the xml one or the xmlns one.
(node->xml-string (xml-element (xml-name "p")
                               (list (Tuple (xml-name "class") "note"))
                               (list (xml-text "hi"))))
;; (Ok "<p class=\"note\">hi</p>")

See also: node->xml, document->xml-string

document->xml

function

(: document->xml (-> Document TextOutputPort (#:indent? bool) (#:prefixes (List (Tuple string string))) (#:declaration? bool) (Result XmlWriteError Unit)))
(document->xml doc port #:indent? #f #:prefixes Nil #:declaration? #t)

Writes a document as XML to a port.

doc
The document.
port
Where to write it. It is left open.
#:indent?
Whether to put an element's children, and the nodes around the root, on lines of their own.
#:prefixes
Prefixes to use, as (Tuple prefix uri).
#:declaration?
Whether to begin with the XML declaration.
returns
Ok, or the XmlWriteError for what could not be written. What was written before it stays written.
raises ArgumentException
When a hint in #:prefixes could not be a prefix, or names no namespace, the xml one or the xmlns one.

The declaration is <?xml version="1.0"?>, with no encoding, since which one the text ends up in is the port’s business.

See also: document->xml-string, node->xml

document->xml-string

function

(: document->xml-string (-> Document (#:indent? bool) (#:prefixes (List (Tuple string string))) (#:declaration? bool) (Result XmlWriteError string)))
(document->xml-string doc #:indent? #f #:prefixes Nil #:declaration? #t)

A document as a string of XML.

doc
The document.
#:indent?
Whether to put an element's children, and the nodes around the root, on lines of their own.
#:prefixes
Prefixes to use, as (Tuple prefix uri).
#:declaration?
Whether to begin with the XML declaration, <?xml version="1.0"?>.
returns
The XML, or the XmlWriteError for what could not be written.
raises ArgumentException
When a hint in #:prefixes could not be a prefix, or names no namespace, the xml one or the xmlns one.

See also: document->xml, node->xml-string