Converter - Writing XML
Converter schemas are bidirectional where a parsed value has an unambiguous XML
representation. Configure element and attribute names with .writer(), then use
.writeSync(), .write(), or .writeToStream().
Object output
Section titled “Object output”import { x } from 'stax-xml/converter';
const book = x.object({ id: x.string('./@id').writer({ asAttribute: 'id' }), title: x.string('./title').writer({ element: 'title' }), price: x.number('./price').writer({ element: 'price' }), note: x.string('./note').optional().writer({ element: 'note' }),});
const xml = book.writeSync( { id: 'b1', title: 'XML & Streams', price: 29.5, note: undefined }, { rootElement: 'book', includeDeclaration: false },);// <book id="b1"><title>XML & Streams</title><price>29.5</price></book>undefined and null object fields are omitted. Attribute fields are written
on the containing object element. If an element field omits element, its
object key is used as the element name.
Nested objects and arrays
Section titled “Nested objects and arrays”const catalog = x.object({ owner: x.object({ name: x.string('./name').writer({ element: 'name' }), }).writer({ element: 'owner' }), books: x.array( x.object({ title: x.string('./title').writer({ element: 'title' }), }).writer({ element: 'book' }), ).writer({ element: 'books' }),});
const xml = await catalog.write( { owner: { name: 'Ada' }, books: [{ title: 'One' }, { title: 'Two' }] }, { rootElement: 'catalog', includeDeclaration: false },);// <catalog><owner><name>Ada</name></owner><books><book><title>One</title></book><book><title>Two</title></book></books></catalog>The array schema’s element names the collection element when the array is an
object field. The array’s element schema must provide its item element name.
Non-empty arrays without an item element name are rejected.
rootElement is an optional outer wrapper. A top-level schema configured with
its own element keeps that element inside the wrapper; omit rootElement to
use the schema element itself as the document element.
Writer configuration
Section titled “Writer configuration”interface XmlElementWriteConfig { element?: string; asAttribute?: string; namespace?: { prefix?: string; uri: string; }; cdata?: boolean; selfClosing?: boolean; comment?: string;}elementnames an element. Object fields may use the field key instead.asAttributewrites the field on its containing object element.namespacedeclares a namespace using XML Namespaces rules. An omitted prefix declares the default namespace.cdatawrites scalar string content as CDATA. Content containing]]>is rejected.selfClosingemits/>only when the configured element is empty.commentwrites a validated XML comment before the element.
const value = x.string().writer({ element: 'value', namespace: { prefix: 'm', uri: 'urn:metrics' },});
value.writeSync('42', { rootElement: 'root', includeDeclaration: false });// <root><m:value xmlns:m="urn:metrics">42</m:value></root>Namespace prefixes and local names are validated as XML NCNames. Reserved
xml / xmlns bindings, undeclared prefixes, and duplicate expanded
attributes are rejected.
Output options
Section titled “Output options”interface XmlWriteOptions { prettyPrint?: boolean; indentString?: string; encoding?: 'utf-8' | 'UTF-8'; rootElement?: string; includeDeclaration?: boolean; xmlVersion?: '1.0'; writer?: WriterSync | WriterSyncSink | Writer;}The v1 parser and writers implement XML 1.0. Reader byte input can select a
host-supported TextDecoder encoding. Built-in string and byte writer targets
use UTF-8; an injected AsyncTextSink or encoded WriterSyncSink can declare
its external encoding. Mismatched encodings and XML 1.1 declarations are rejected.
Element text, attributes, comments, CDATA, namespace URIs, and
processing-instruction data reject characters forbidden by XML 1.0.
Synchronous and asynchronous converter writers have the same output semantics:
const options = { rootElement: 'book', includeDeclaration: false } as const;const syncXml = book.writeSync(data, options);const asyncXml = await book.write(data, options);// syncXml === asyncXmlFor large output, stream directly instead of collecting a string:
await catalog.writeToStream(data, writableStream, { rootElement: 'catalog', includeDeclaration: true,});Unsupported output
Section titled “Unsupported output”- Transform schemas cannot be written because a transform is not necessarily reversible; write with the underlying schema or define an explicit inverse.
NaNand infinities are rejected by number writers.- Attribute fields require a containing object element.
writeRaw()belongs to the low-level writers and accepts trusted XML only; converter scalar writers use validated character or CDATA methods.
See Schema Types for parsing and Writer for the lower-level streaming writer.