std/xml/xml

std/xml/src/xml.trb

Xml, the format: a value with the options of XML, which reads a document into the tree of XmlNodes and writes that tree back.

type Xml

type Xml

XML, with its options. XML 1.0 (fifth edition) with Namespaces in XML 1.0: Xml.parse reads a document into an XmlNode and Xml.write writes the tree back.

The reader is a well-formedness checker and not a validator. It never opens an external entity or an external subset. It reads the internal subset of a document type declaration: the general and the parameter entities it declares are expanded in content and in attribute values (the replacement text is parsed as content and has to be well-balanced), and the element, notation, comment and instruction declarations are checked and skipped. The attribute-list declarations give an element the attributes it lacks, with their default values, and normalise the values of a type other than CDATA further; a defaulted xmlns takes part in the namespaces of the element. An external or unparsed entity is recorded and an error where it is referenced. The Doctype node keeps the name and the identifiers and not the subset, and Xml.write writes it without one.

Examples

const tree = Xml().parse("<a xmlns=\"urn:example\"><b>text</b></a>")?
print tree.root()?.child("b")?.text()
print(Xml().write(tree)?)

Related

  • XmlNode - the tree of a document.
  • XmlError - what a failed parse or write says.

field indent

indent: Int = 0

How many spaces the writer indents a level with. 0, the default, writes the tree as it is. Above 0 an element that holds no text puts each child on a line of its own; that adds white space, which a reader keeps as text, so the written tree is no longer equal to the one it was written from.

field entityLimit

entityLimit: Int = 1000000

How many characters the references to the entities of a document may add to it, in all: a document that declares entities within entities is cut off at this size and is an XmlError that names entityLimit, instead of filling the memory (the "billion laughs"). The default, 1000000, is far beyond any document that is not an attack; raise it for a trusted document that needs more.

fn parse

fn parse(text: String): Result<XmlNode, XmlError>

Reads text, one XML document, into a tree: an XmlNode.Document whose children are the comments, instructions, the document type declaration if there is one, and the root element. Line breaks are read as \n, an attribute value is normalised as XML 1.0 says, and every name is resolved against the namespaces in force.

Errors

An XmlError with the line and the column of the problem for a text that is not well-formed, a prefix that is not declared, a name that breaks the rules of namespaces, an entity that is not declared, external, unparsed or recursive, a replacement text that is not well-balanced, a default value that breaks one of those rules where it is used, and an expansion past Xml.entityLimit. An error inside an expansion has the place of the reference.

fn write

fn write(tree: XmlNode): Result<String, XmlError>

tree as XML text. A namespace the tree uses without declaring it is declared on the element that needs it, and parse(write(tree)) is tree for every tree that parse made.

Errors

An XmlError with line 0 for a tree XML cannot say: a name that is no name, a character that is not allowed, a comment with -- in it, a CDATA section with ]]>, or a document without exactly one root element.