Skip to content

Instantly share code, notes, and snippets.

@pyrsmk
Created January 19, 2022 17:38
Show Gist options
  • Save pyrsmk/46e73e3ed488dd7e8bc88360d7199465 to your computer and use it in GitHub Desktop.
Save pyrsmk/46e73e3ed488dd7e8bc88360d7199465 to your computer and use it in GitHub Desktop.
Convert XML files to JS objects.
// It converts simple XML structures to JS objects. The default value of a node is an
// empty string, as it should be (contrary to several libraries I tested).
const { DOMParser } = require('@xmldom/xmldom')
const loadChildNodesRecursive = node => {
const nodes = {}
Array.from(node.childNodes)
.filter(element => element.nodeType === element.ELEMENT_NODE)
.forEach(element => {
let value
// `<element></element>` or `<element/>`
if (element.childNodes.length === 0) {
value = ''
// `<element>foo</element>`
} else if (element.childNodes.length === 1 &&
element.childNodes[0].nodeValue !== null) {
value = element.childNodes[0].nodeValue
// ```
// <element>
// <foo></foo>
// <bar></bar>
// <etc></etc>
// </element>
// ```
//
// or
//
// `<element><foo></foo><bar></bar><etc></etc></element>`
//
// or
//
// `<element><foo></foo></element>`
} else if (element.childNodes.length > 1 ||
element.childNodes[0].nodeValue === null) {
value = loadChildNodesRecursive(element)
}
// Property is not defined, let's just assign the value.
if (nodes[element.tagName] === undefined) {
nodes[element.tagName] = value
return
}
// Property is already defined, we need to convert it to an array if necessary.
if (!Array.isArray(nodes[element.tagName])) {
nodes[element.tagName] = [nodes[element.tagName]]
}
// Property already exists, let's add the new value to the stack.
nodes[element.tagName].push(value)
})
return nodes
}
module.exports = contents => {
const handler = message => {
throw new Error(message)
}
const domParser = new DOMParser(
{ errorHandler: { warning: handler, error: handler, fatalError: handler} }
)
return loadChildNodesRecursive(
domParser.parseFromString(contents)
)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment