-
Notifications
You must be signed in to change notification settings - Fork 4
XMLMarshaller
XMLMarshaller is a companion class to XMLSchemata implementing serialization of data objects to XML string according to a given XML schema element (normally, a complex type).
const xs = await XMLSchemata.fromFile ('wsdl_related_stuff.xsd')
const m = xs.createMarshaller (localName, namespaceURI)
const xml = m.stringify (data /*, {
// localName : 'otherThanDataRootKey',
// declaration : {encoding: 'UTF-5'},
}*/)XMLMarshaller can be considered a JSON to XML converter: it does the almost exactly opposite to XMLNode.toObject, with similar (but inverse) structure transformations.
-
booleanvalues are always written asfalseortrue; a mapping is predefined for strings'0'/'1','false'/'true','N'/'Y', other values are subject to standardtoBoolean; - if a Number or a BigInt is supplied for a
dateordateTimefield, it's used as an argument for theDateconstructor (number of milliseconds since 1970-01-01); - for a
datefield, any string of length 10 is passed through unchecked (it's expected to de inYYYY-MM-DDformat, be careful), otherwise theDateobject is constructed and (re)serialized; - for
integerand all its descendants, a BigInt or (forintand shorter types) a Number is created, checked and then serialized; - for
floatanddouble, a Number is created withparseFloat, then serialized; - for
decimaltoo,parseFloatis used, but then, iffractionDigitsrestriction is set, the string is formed withtoFixed; -
QNames are expected to be supplied as{localName, namespaceURI}objects, for which qualified names are generated according to the current namespace map; - all other values are converted
toString, special characters are escaped.
Attribute only elements are naturally mapped from scalar valued plain objects:
{Order: {amount: 1, price: 2.34}} // <Order amount="1" price="2.34"/>Text only child elements are normally represented by scalar properties of data objects:
{Outer: {Inner: 123}} // <Outer><Inner>123</Inner></Outer>But how to represent data for elements with both attributes and text content? In this case, the text must be presented as a null named pseudo attribute:
{Request: {Id: 1, null: 'HELO'}} // <Request Id="1">HELO</Request>Some schemata (like SOAP 1.1) contain any and anyAttribute wildcards corresponding to XML fragments of unknown structure.
For stringify to fill in such a wildcard, the content must be presented as a special object with null key is provided:
xs.stringify ({
Envelope: {
Body: { // contains xs:any, xs:anyAttribute
null: { // cannot be localName, so no possible confilct here
'<someRequest>CODE</someRequest>': // raw XML content to be injected as xs:any
{Id: 1 /*, ...*/} // "any" attributes key/value pairs
}},
}
}
)yields
<ns0:Envelope xmlns:ns0="http://schemas.xmlsoap.org/soap/envelope/">
<ns0:Body Id="1"><someRequest>CODE</someRequest></ns0:Body>
</ns0:Envelope>In application code, such values may be produced with the XMLSchemata.any convenience method.
- Probably forever:
- Virtually no validation of any kind
- except for edge cases like a
truevalue for adateTimefield: then, XMLMarshaller will throw an error - and, maybe, later, for exotic scalar types like gDay)
- except for edge cases like a
- No
xsi:typepolymorphism
- Virtually no validation of any kind
- Minor performance issues not to be fixed shortly:
- Elements with zero length content have explicit closing tags, self enclosing is not used.
-
"are escaped as"not only in attribute values, but in text nodes too.
- Pesky things
-
choiceis implemented as an alias tosequence: if data are supplied for two or more branches of onechoice, the result will be invalid. -
hexBinaryandbase64Binaryencoding should be supported forBuffervalues.
-
Generates the XML declaration pseudo-tag.
const decl = XMLMarshaller.declaration ({
version: 3.14159, // '1.0' by default
encoding: 'UTF-6', // no default; may be missing
standalone: 'no', // no default; may be missing
})