Some XML helpers to help with OOXML development
Note
These are all based around xml-js
and output that modules internal format
When working with xml-js
it's really handy to not have to worry about when you're passing an XML string our the xml-js
JSON type called Element
This helper function just outputs an Element
for either input
asXmlElement("<name>foo</name>") // => {name: "name", text: "foo"}
asXmlElement({name: "name", text: "foo"}) // => {name: "name", text: "foo"}
Note
All the other functions in this document that accept XML, also accept this Element
(using this function)
An XML tagged template literal with the following features
- error if XML is incorrect
- array support in substitution
The following will error in development, because of mismatched start/end tags
safeXml`<foo>hello</bar>`
Substitution of arrays "just works" so you can map values in the tagged template literals
const items = [1,2,3].map(n => safeXml`<name>item ${1}</name>`);
const outXml = safeXml`<test>${items}</test>`
assert.equal(outXml, `<test><name>item 1</name><name>item 2</name><name>item 3</name></test>`);
This also makes it easy to support https://prettier.io/docs/en/options#embedded-language-formatting
Removes non required whitespace from the XML
const outXml = compact(`
<test>
something
</test>
`);
assert.equal(outXml, "<test>something</test>");
For XML to be valid, there must be a single root node. When composing apps it's handy for that not to be true.
For example the following would error
const xml = safeXml`
<name>foo</name>
<name>bar</name>
`
So instead we'd like something like a HTML fragment
const xml = safeXml`
<XML_FRAGMENT>
<name>foo</name>
<name>bar</name>
</XML_FRAGMENT>
`
So we did just that, removeFragments
walks over a tree removing <XML_FRAGMENT>...</XML_FRAGMENT>
nodes.
const innerBit = safeXml`
<XML_FRAGMENT>
<name>foo</name>
<name>bar</name>
</XML_FRAGMENT>
`
const newXml = removeFragments(
safeXml`
<doc>
${innerBit}
</doc>
`
)
assert.equal(newXml, `
<doc>
<name>foo</name>
<name>bar</name>
</doc>
`)
From the wikipedia page
CDATA section is a piece of element content that is marked up to be interpreted literally, as textual data, not as marked-up content.
But <name><![CDATA[one < two]]><name>
is ugly and hard to read, so instead
safeXml`<name>${cdata("one < two")}</name>`
MIT