/** * XMLtoObject - Converts XML into a JavaScript value or object. * GitHub: https://github.com/Pevtrick/XMLtoObject * by Patrick Jentsch: https://github.com/Pevtrick */ /** * The XMLDocument.toObject() method converts the XMLDocument into a JavaScript value or object. * @param {String} [attributePrefix=] - A Prefix, which is added to all properties generated by XML attributes. * @returns {Object} - The converted result. */ XMLDocument.prototype.toObject = function(attributePrefix='') { let obj = {}; obj[this.documentElement.nodeName] = this.documentElement.toObject(attributePrefix); return obj; }; /** * The Node.toObject() method converts the Node into a JavaScript value or object. * @param {String} [attributePrefix=] - A Prefix, which is added to all properties generated by XML attributes. * @returns {Object|String|null} - The converted result. */ Node.prototype.toObject = function(attributePrefix='') { let obj = null; switch (this.nodeType) { case Node.ELEMENT_NODE: let hasAttributes = this.attributes.length > 0; let hasChildNodes = this.childNodes.length > 0; /* Stop conversion if the Node doesn't contain any attributes or child nodes */ if (!(hasAttributes || hasChildNodes)) { break; } obj = {}; /* Convert attributes */ for (let attribute of this.attributes) { obj[`attributePrefix${attribute.name}`] = attribute.value; } /* Convert child nodes */ for (let childNode of this.childNodes) { switch (childNode.nodeType) { case Node.ELEMENT_NODE: break; case Node.TEXT_NODE: /* Check whether the child text node is the only child of the current node. */ if (!hasAttributes && this.childNodes.length === 1) { obj = childNode.toObject(attributePrefix); continue; } if (childNode.data.trim() === '') {continue;} break; default: /* This recursion leads to a console message. */ childNode.toObject(attributePrefix); continue; } /** * If the child node is the first of its type in this childset, * process it and add it directly as a property to the return object. * If not add it to an array which is set as a property of the return object. */ if (childNode.nodeName in obj) { if (!Array.isArray(obj[childNode.nodeName])) { obj[childNode.nodeName] = [obj[childNode.nodeName]]; } obj[childNode.nodeName].push(childNode.toObject(attributePrefix)); } else { obj[childNode.nodeName] = childNode.toObject(attributePrefix); } } break; case Node.TEXT_NODE: if (this.data.trim() !== '') {obj = this.data;} break; case Node.COMMENT_NODE: console.log('Skipping comment node:'); console.log(node); break; case Node.DOCUMENT_NODE: obj = {}; obj[this.documentElement.nodeName] = this.documentElement.toObject(attributePrefix); break; default: /** * The following node types are not processed because they don't offer data, which has to be stored in the object: * Node.PROCESSING_INSTRUCTION_NODE, Node.DOCUMENT_TYPE_NODE, Node.DOCUMENT_FRAGMENT_NODE * The following node types are deprecated and therefore not supported by this function: * Node.ATTRIBUTE_NODE, Node.CDATA_SECTION_NODE, Node.ENTITY_REFERENCE_NODE, Node.ENTITY_NODE, Node.NOTATION_NODE */ console.log(`Node type: '${this.nodeType}' is not supported.`); console.log(node); break; } return obj; }