XML literals
XML literals are a new feature in Kawa. They make it more convenient to write XML data objects, especially if you're familar with XML syntax. (This is an extract from the SVN version of the Kawa manual.)You can write XML literals directly in Scheme code,
following a #
.
Notice that the outermost element needs to be prefixed
by #
, but nested elements do (and must not).
#<p>The result is <b>final</b>!</p>
Actually, these are not really literals since they can contain enclosed expressions:
#<em>The result is &{result}.</em>
The value of result is substituted into the output, in a similar way to quasi-quotation. (If you try to quote one of these “XML literals”, what you get is unspecified and is subject to change.)
An xml-literal is usually an element constructor, but there some rarely used forms (processing-instructions, comments, and CDATA section) we'll cover later.
xml-literal::=
#
xml-constructor xml-constructor::=
xml-element-constructor | xml-PI-constructor | xml-comment-constructor | xml-CDATA-constructor
Element constructors
xml-element-constructor::=
<
QName xml-attribute*>
xml-element-datum...</
QName>
|<
xml-name-form xml-attribute*>
xml-element-datum...</>
|<
xml-name-form xml-attribute*/>
xml-name-form::=
QName | xml-enclosed-expression xml-enclosed-expression::=
{
expression}
|(
expression...)
The first xml-element-constructor variant uses a literal QName, and looks like standard non-empty XML element, where the starting QName and the ending QName must match exactly:
#<a href="next.html">Next</a>
As a convenience, you can leave out the ending tag(s):
<para>This is a paragraph in <emphasis>DocBook</> syntax.</>
You can use an expression to compute the element tag at runtime - in that case you must leave out the ending tag:
#<p>This is <(if be-bold 'strong 'em)>important</>!</p>
You can use arbitrary expression inside curly braces, as long as it evaluates to a symbol. You can leave out the curly braces if the expression is a simple parenthesised compound expression. The previous example is equivalent to:
#<p>This is <{(if be-bold 'strong 'em)}>important</>!</p>
The third xml-element-constructor variant above is an XML “empty element”; it is equivalent to the second variant when there are no xml-element-datum items.
(Note that every well-formed XML element, as defined in the XML specifications, is a valid xml-element-constructor, but not vice versa.)
Elements contents (children)
The “contents” (children) of an element
are a sequence of character (text) data, and nested nodes.
The characters &
, <
, and >
are special,
and need to be escaped.
xml-element-datum::=
any character except&
, or<
. | xml-constructor | xml-escaped xml-escaped::=
&
xml-enclosed-expression |&
xml-entity-name;
| xml-character-reference xml-character-reference::=
&#
decimal-digit+;
|&#x
hex-digit+;
Here is an example shows both hex and decimal character references:
#<p>ABCDE</p> ⇒ <p>ABCDE</p>
Currently, the only supported values for xml-entity-name
are the builtin XML names lt
, gt
, amp
,
quot
, and apos
, which stand for the characters
<
, >
, &
, "
, and '
, respectively.
The following two expressions are equivalent:
#<p>< > & " '</p> #<p>&{"< > & \" '"}</p>
Attributes
xml-attribute::=
xml-name-form=
xml-attribute-value xml-attribute-value::=
"
quot-attribute-datum*"
|'
apos-attribute-datum*'
quot-attribute-datum::=
any character except"
,&
, or<
. | xml-escaped apos-attribute-datum::=
any character except'
,&
, or<
. | xml-escaped
If the xml-name-form is either xmlns
or
a compound named with the prefix xmlns
, then
technically we have a namespace declaration, rather than
an attribute.
QNames and namespaces
The names of elements and attributes are qualified names (QNames), which are represented using compound symbols (see Namespaces). The lexical syntax for a QName is either a simple identifier, or a (prefix,local-name) pair:
QName::=
xml-local-part | xml-prefix:
xml-local-part xml-local-part::=
identifier xml-prefix::=
identifier
An xml-prefix is an alias for a namespace-uri,
and the mapping between them is defined by a namespace-declaration.
You can either use a define-namespace
form, or you
can use a namespace declaration attribute:
xml-namespace-declaration-attribute::=
xmlns:
xml-prefix=
xml-attribute-value |xmlns=
xml-attribute-value
The former declares xml-prefix as a namespace alias for the namespace-uri specified by xml-attribute-value (which must be a compile-time constant). The second declares that xml-attribute-value is the default namespace for simple (unprefixed) element tags. (A default namespace declaration is ignored for attribute names.)
(let ((qn (element-name #<gnu:b xmlns:gnu="http://gnu.org/"/>))) (list (symbol-local-name qn) (symbol-prefix qn) (symbol-namespace-uri qn))) ⇒ ("b" "gnu" "http://gnu.org/")
Other XML types
Processing instructions
An xml-PI-constructor can be used to create an XML
processing instruction, which can be used to pass
instructions or annotations to an XML processor (or tool).
(Alternatively, you can use the processing-instruction
type constructor.)
xml-PI-constructor::=
<?
xml-PI-target xml-PI-content?>
xml-PI-target::=
NCname (i.e. a simple (non-compound) identifier) xml-PI-content::=
any characters, not containing?>
.
For example, the DocBook XSLT stylesheets can use the dbhtml
instructions to specify that a specific chapter should be
written to a named HTML file:
#<chapter><?dbhtml filename="intro.html" ?> <title>Introduction</title> ... </chapter>
XML comments
You can cause XML comments to be emitted in the XML output document.
Such comments can be useful for humans reading the XML document,
but are usually ignored by programs.
(Alternatively, you can use the comment
type constructor.)
xml-comment-constructor::=
<!--
xml-comment-content-->
xml-comment-content::=
any characters, not containing--
.
CDATA sections
A CDATA
section can be used to avoid excessive use of
xml-entity-ref such as &
in element content.
xml-CDATA-constructor::=
<![CDATA[
xml-CDATA-content]]>
xml-CDATA-content::=
any characters, not containing]]>
.
The following are equivalent:
#<p>Specal characters <![CDATA[< > & ' "]]> here.</p> #<p>Specal characters < > & " ' here.</p>
Kawa remembers that you used a CDATA
section in
the xml-element-constructor and will write it out
using a CDATA
constructor.