UNPKG

@openxmldev/linq-to-xml

Version:
116 lines 4.84 kB
/** * @author Thomas Barnekow * @license MIT */ import { XAttribute, XDocument, XElement, XNamespace, XProcessingInstruction, } from './internal.js'; /** * Provides utility functions for parsing XML. * * @internal */ export class DomReader { /** @internal */ static getXName(node) { const namespace = this.getXNamespace(node); const localName = node.localName; // Deal with default namespace declarations which, in the DOM, will have: // - namespaceName === 'http://www.w3.org/2000/xmlns/' and // - localName === 'xmlns' return namespace === XNamespace.xmlns && localName === 'xmlns' ? XNamespace.none.getName('xmlns') : namespace.getName(localName); } /** @internal */ static getXNamespace(node) { const namespaceName = node.namespaceURI; return namespaceName ? XNamespace.get(namespaceName) : XNamespace.none; } /** * Creates a new `XDocument` from the given DOM `XMLDocument`. * * @param xmlDocument The DOM `XMLDocument` to be loaded. * @returns A new `XDocument` instance. */ static loadXDocument(xmlDocument) { const xdocument = new XDocument(); xmlDocument.childNodes.forEach((node) => { xdocument.add(this.loadXNode(node)); }); return xdocument; } /** * Creates a new `XElement` from the given DOM `Element`. * * @param element The `Element` to be loaded. * @returns A new `XElement` instance. */ static loadXElement(element) { const xelement = new XElement(this.getXName(element)); // Add all XAttributes. for (let i = 0; i < element.attributes.length; i++) { const attribute = element.attributes[i]; xelement.add(new XAttribute(this.getXName(attribute), attribute.value)); } // Add all XNodes. element.childNodes.forEach((node) => { xelement.add(this.loadXNode(node)); }); return xelement; } /** * Creates an `XDocument`, `XElement`, `XProcessingInstruction`, or `string` * from the given node. Returns `null` for text nodes without a nodeValue. * Throws exceptions for unsupported and unexpected node types: * * - COMMENT_NODE: Currently unsupported (not used in Open XML) * - CDATA_SECTION_NODE: Currently unsupported (not used in Open XML) * - DOCUMENT_TYPE_NODE: Unsupported (not used in XML) * * Notes: * - Returns a `string` instead of an `XText` in line with the Linq-to-XML * practice of storing text-only nodes as strings at least initially. * * - A DOM Node represents both nodes and attributes, whereas in Linq-to-XML * an XAttribute is not an XNode. Therefore, this method does not expect * attribute "nodes". * * @param node The `Node`. * @returns An `XDocument`, `XElement`, `XProcessingInstruction`, `string`, or `null`. * * @internal */ static loadXNode(node) { // Note that there is no nodeType constant for XML declarations. This is // due to the fact that the DOM is focused on HTML documents, where XML // declarations don't exist. switch (node.nodeType) { case Node.ELEMENT_NODE: return this.loadXElement(node); case Node.TEXT_NODE: return node.nodeValue; case Node.PROCESSING_INSTRUCTION_NODE: { const pi = node; return new XProcessingInstruction(pi.target, pi.data); } case Node.DOCUMENT_NODE: // This case exists mostly to be complete. You'd typically call // loadXDocument() from the outside, so this is not normally hit. return this.loadXDocument(node); case Node.COMMENT_NODE: // With the focus on Open XML markup, we currently don't support // Comment nodes such as <!-- … --> throw new Error('Unsupported Comment node.'); case Node.CDATA_SECTION_NODE: // With the focus on Open XML markup, we currently don't support // CDATASection nodes such as <!CDATA[[ … ]]>. throw new Error('Unsupported CDATASection node.'); case Node.DOCUMENT_TYPE_NODE: // DocumentType nodes such as <!DOCTYPE html> don't exist in XML. throw new Error('Unsupported DocumentType node.'); default: // This should never happen. throw new Error(`Unexpected nodeType: ${node.nodeType}`); } } } //# sourceMappingURL=DomReader.js.map