XML is not my favorite data exchange format, but sometimes you have no choice. So if it comes to the question how to handle those data in JavaScript, I first want to use an existing npm module that flies around in the www. But on second sight I found a even simpler solution, that does not need anything, except the browser who is already there.
The browser has a parser build in, who can also parse given XML data. Let’s try to use it.
The first step towards my content goes through a request I have done with fetch.
const result = await fetch(requestUrl)
const xml = await result.text()
The next an almost final step, easy as is, was to parse the result.
const domParser = new DOMParser()
const xmlDocument = domParser.parseFromString(xml, 'text/xml')
And then we are almost there. The last step is to get something out of this DOM nodes, what can easily be used in JavaScript: an Object.
index.js
export default from './xml-parser'
xml-parser.js
const api = {
xmlToJson (xml) {
let jsonData = {}
if (xml.nodeType === 1) {
if (xml.attributes.length > 0) {
jsonData.attributes = {}
for (let j = 0; j < xml.attributes.length; j++) {
const attribute = xml.attributes.item(j)
jsonData.attributes[attribute.nodeName] = attribute.nodeValue
}
}
}
const textNodes = [].slice.call(xml.childNodes).filter(node => node.nodeType === 3)
if (xml.hasChildNodes() && xml.childNodes.length === textNodes.length) {
jsonData = [].slice.call(xml.childNodes).reduce((text, node) => text + node.nodeValue, '')
} else if (xml.hasChildNodes()) {
for (let i = 0; i < xml.childNodes.length; i++) {
const item = xml.childNodes.item(i)
const nodeName = item.nodeName.replace(':', '_')
if (nodeName !== '#text') {
if (typeof jsonData[nodeName] === 'undefined') {
jsonData[nodeName] = this.xmlToJson(item)
} else {
if (typeof jsonData[nodeName].push === 'undefined') {
const old = jsonData[nodeName]
jsonData[nodeName] = []
jsonData[nodeName].push(old)
}
jsonData[nodeName].push(this.xmlToJson(item))
}
}
}
}
return jsonData
},
}
export default api
And that’s it.
See You