﻿/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
 

/** @module datajs/xml */

var utils    = require('./utils.js');

var activeXObject = utils.activeXObject;
var djsassert = utils.djsassert;
var extend = utils.extend;
var isArray = utils.isArray;
var normalizeURI = utils.normalizeURI;

// URI prefixes to generate smaller code.
var http = "http://";
var w3org = http + "www.w3.org/";               // http://www.w3.org/

var xhtmlNS = w3org + "1999/xhtml";             // http://www.w3.org/1999/xhtml
var xmlnsNS = w3org + "2000/xmlns/";            // http://www.w3.org/2000/xmlns/
var xmlNS = w3org + "XML/1998/namespace";       // http://www.w3.org/XML/1998/namespace

var mozillaParserErroNS = http + "www.mozilla.org/newlayout/xml/parsererror.xml";

/** Checks whether the specified string has leading or trailing spaces.
 * @param {String} text - String to check.
 * @returns {Boolean} true if text has any leading or trailing whitespace; false otherwise.
 */
function hasLeadingOrTrailingWhitespace(text) {
    var re = /(^\s)|(\s$)/;
    return re.test(text);
}

/** Determines whether the specified text is empty or whitespace.
 * @param {String} text - Value to inspect.
 * @returns {Boolean} true if the text value is empty or all whitespace; false otherwise.
 */
function isWhitespace(text) {


    var ws = /^\s*$/;
    return text === null || ws.test(text);
}

/** Determines whether the specified element has xml:space='preserve' applied.
 * @param domElement - Element to inspect.
 * @returns {Boolean} Whether xml:space='preserve' is in effect.
 */
function isWhitespacePreserveContext(domElement) {


    while (domElement !== null && domElement.nodeType === 1) {
        var val = xmlAttributeValue(domElement, "space", xmlNS);
        if (val === "preserve") {
            return true;
        } else if (val === "default") {
            break;
        } else {
            domElement = domElement.parentNode;
        }
    }

    return false;
}

/** Determines whether the attribute is a XML namespace declaration.
 * @param domAttribute - Element to inspect.
 * @return {Boolean} True if the attribute is a namespace declaration (its name is 'xmlns' or starts with 'xmlns:'; false otherwise.
 */
function isXmlNSDeclaration(domAttribute) {
    var nodeName = domAttribute.nodeName;
    return nodeName == "xmlns" || nodeName.indexOf("xmlns:") === 0;
}

/** Safely set as property in an object by invoking obj.setProperty.
 * @param obj - Object that exposes a setProperty method.
 * @param {String} name - Property name
 * @param value - Property value.
 */
function safeSetProperty(obj, name, value) {


    try {
        obj.setProperty(name, value);
    } catch (_) { }
}

/** Creates an configures new MSXML 3.0 ActiveX object.
 * @returns {Object} New MSXML 3.0 ActiveX object.
 * This function throws any exception that occurs during the creation
 * of the MSXML 3.0 ActiveX object.
 */
function msXmlDom3() {
    var msxml3 = activeXObject("Msxml2.DOMDocument.3.0");
    if (msxml3) {
        safeSetProperty(msxml3, "ProhibitDTD", true);
        safeSetProperty(msxml3, "MaxElementDepth", 256);
        safeSetProperty(msxml3, "AllowDocumentFunction", false);
        safeSetProperty(msxml3, "AllowXsltScript", false);
    }
    return msxml3;
}

/** Creates an configures new MSXML 6.0 or MSXML 3.0 ActiveX object.
 * @returns {Object} New MSXML 3.0 ActiveX object.
 * This function will try to create a new MSXML 6.0 ActiveX object. If it fails then
 * it will fallback to create a new MSXML 3.0 ActiveX object. Any exception that
 * happens during the creation of the MSXML 6.0 will be handled by the function while
 * the ones that happend during the creation of the MSXML 3.0 will be thrown.
 */
function msXmlDom() {
    try {
        var msxml = activeXObject("Msxml2.DOMDocument.6.0");
        if (msxml) {
            msxml.async = true;
        }
        return msxml;
    } catch (_) {
        return msXmlDom3();
    }
}

/** Parses an XML string using the MSXML DOM.
 * @returns {Object} New MSXML DOMDocument node representing the parsed XML string.
 * This function throws any exception that occurs during the creation
 * of the MSXML ActiveX object.  It also will throw an exception
 * in case of a parsing error.
 */
function msXmlParse(text) {
    var dom = msXmlDom();
    if (!dom) {
        return null;
    }

    dom.loadXML(text);
    var parseError = dom.parseError;
    if (parseError.errorCode !== 0) {
        xmlThrowParserError(parseError.reason, parseError.srcText, text);
    }
    return dom;
}

/** Throws a new exception containing XML parsing error information.
 * @param exceptionOrReason - String indicating the reason of the parsing failure or Object detailing the parsing error.
 * @param {String} srcText -     String indicating the part of the XML string that caused the parsing error.
 * @param {String} errorXmlText - XML string for wich the parsing failed.
 */
function xmlThrowParserError(exceptionOrReason, srcText, errorXmlText) {

    if (typeof exceptionOrReason === "string") {
        exceptionOrReason = { message: exceptionOrReason };
    }
    throw extend(exceptionOrReason, { srcText: srcText || "", errorXmlText: errorXmlText || "" });
}

/** Returns an XML DOM document from the specified text.
 * @param {String} text - Document text.
 * @returns XML DOM document.
 * This function will throw an exception in case of a parse error
 */
function xmlParse(text) {
    var domParser = window.DOMParser && new window.DOMParser();
    var dom;

    if (!domParser) {
        dom = msXmlParse(text);
        if (!dom) {
            xmlThrowParserError("XML DOM parser not supported");
        }
        return dom;
    }

    try {
        dom = domParser.parseFromString(text, "text/xml");
    } catch (e) {
        xmlThrowParserError(e, "", text);
    }

    var element = dom.documentElement;
    var nsURI = element.namespaceURI;
    var localName = xmlLocalName(element);

    // Firefox reports errors by returing the DOM for an xml document describing the problem.
    if (localName === "parsererror" && nsURI === mozillaParserErroNS) {
        var srcTextElement = xmlFirstChildElement(element, mozillaParserErroNS, "sourcetext");
        var srcText = srcTextElement ? xmlNodeValue(srcTextElement) : "";
        xmlThrowParserError(xmlInnerText(element) || "", srcText, text);
    }

    // Chrome (and maybe other webkit based browsers) report errors by injecting a header with an error message.
    // The error may be localized, so instead we simply check for a header as the
    // top element or descendant child of the document.
    if (localName === "h3" && nsURI === xhtmlNS || xmlFirstDescendantElement(element, xhtmlNS, "h3")) {
        var reason = "";
        var siblings = [];
        var cursor = element.firstChild;
        while (cursor) {
            if (cursor.nodeType === 1) {
                reason += xmlInnerText(cursor) || "";
            }
            siblings.push(cursor.nextSibling);
            cursor = cursor.firstChild || siblings.shift();
        }
        reason += xmlInnerText(element) || "";
        xmlThrowParserError(reason, "", text);
    }

    return dom;
}

/** Builds a XML qualified name string in the form of "prefix:name".
 * @param {String} prefix - Prefix string (may be null)
 * @param {String} name - Name string to qualify with the prefix.
 * @returns {String} Qualified name.
 */
function xmlQualifiedName(prefix, name) {
    return prefix ? prefix + ":" + name : name;
}

/** Appends a text node into the specified DOM element node.
 * @param domNode - DOM node for the element.
 * @param {String} text - Text to append as a child of element.
*/
function xmlAppendText(domNode, textNode) {
    if (hasLeadingOrTrailingWhitespace(textNode.data)) {
        var attr = xmlAttributeNode(domNode, xmlNS, "space");
        if (!attr) {
            attr = xmlNewAttribute(domNode.ownerDocument, xmlNS, xmlQualifiedName("xml", "space"));
            xmlAppendChild(domNode, attr);
        }
        attr.value = "preserve";
    }
    domNode.appendChild(textNode);
    return domNode;
}

/** Iterates through the XML element's attributes and invokes the callback function for each one.
 * @param element - Wrapped element to iterate over.
 * @param {Function} onAttributeCallback - Callback function to invoke with wrapped attribute nodes.
*/
function xmlAttributes(element, onAttributeCallback) {
    var attributes = element.attributes;
    var i, len;
    for (i = 0, len = attributes.length; i < len; i++) {
        onAttributeCallback(attributes.item(i));
    }
}

/** Returns the value of a DOM element's attribute.
 * @param domNode - DOM node for the owning element.
 * @param {String} localName - Local name of the attribute.
 * @param {String} nsURI - Namespace URI of the attribute.
 * @returns {String} - The attribute value, null if not found (may be null)
 */
function xmlAttributeValue(domNode, localName, nsURI) {

    var attribute = xmlAttributeNode(domNode, localName, nsURI);
    return attribute ? xmlNodeValue(attribute) : null;
}

/** Gets an attribute node from a DOM element.
 * @param domNode - DOM node for the owning element.
 * @param {String} localName - Local name of the attribute.
 * @param {String} nsURI - Namespace URI of the attribute.
 * @returns The attribute node, null if not found.
 */
function xmlAttributeNode(domNode, localName, nsURI) {

    var attributes = domNode.attributes;
    if (attributes.getNamedItemNS) {
        return attributes.getNamedItemNS(nsURI || null, localName);
    }

    return attributes.getQualifiedItem(localName, nsURI) || null;
}

/** Gets the value of the xml:base attribute on the specified element.
 * @param domNode - Element to get xml:base attribute value from.
 * @param [baseURI] - Base URI used to normalize the value of the xml:base attribute ( may be null)
 * @returns {String} Value of the xml:base attribute if found; the baseURI or null otherwise.
 */
function xmlBaseURI(domNode, baseURI) {

    var base = xmlAttributeNode(domNode, "base", xmlNS);
    return (base ? normalizeURI(base.value, baseURI) : baseURI) || null;
}


/** Iterates through the XML element's child DOM elements and invokes the callback function for each one.
 * @param element - DOM Node containing the DOM elements to iterate over.
 * @param {Function} onElementCallback - Callback function to invoke for each child DOM element.
*/
function xmlChildElements(domNode, onElementCallback) {

    xmlTraverse(domNode, /*recursive*/false, function (child) {
        if (child.nodeType === 1) {
            onElementCallback(child);
        }
        // continue traversing.
        return true;
    });
}

/** Gets the descendant element under root that corresponds to the specified path and namespace URI.
 * @param root - DOM element node from which to get the descendant element.
 * @param {String} namespaceURI - The namespace URI of the element to match.
 * @param {String} path - Path to the desired descendant element.
 * @return The element specified by path and namespace URI.
 * All the elements in the path are matched against namespaceURI.
 * The function will stop searching on the first element that doesn't match the namespace and the path.
 */
function xmlFindElementByPath(root, namespaceURI, path) {
    var parts = path.split("/");
    var i, len;
    for (i = 0, len = parts.length; i < len; i++) {
        root = root && xmlFirstChildElement(root, namespaceURI, parts[i]);
    }
    return root || null;
}

/** Gets the DOM element or DOM attribute node under root that corresponds to the specified path and namespace URI.
 * @param root - DOM element node from which to get the descendant node.
 * @param {String} namespaceURI - The namespace URI of the node to match.
 * @param {String} path - Path to the desired descendant node.
 * @return The node specified by path and namespace URI.</returns>

* This function will traverse the path and match each node associated to a path segement against the namespace URI.
* The traversal stops when the whole path has been exahusted or a node that doesn't belogong the specified namespace is encountered.
* The last segment of the path may be decorated with a starting @ character to indicate that the desired node is a DOM attribute.
*/
function xmlFindNodeByPath(root, namespaceURI, path) {
    

    var lastSegmentStart = path.lastIndexOf("/");
    var nodePath = path.substring(lastSegmentStart + 1);
    var parentPath = path.substring(0, lastSegmentStart);

    var node = parentPath ? xmlFindElementByPath(root, namespaceURI, parentPath) : root;
    if (node) {
        if (nodePath.charAt(0) === "@") {
            return xmlAttributeNode(node, nodePath.substring(1), namespaceURI);
        }
        return xmlFirstChildElement(node, namespaceURI, nodePath);
    }
    return null;
}

/** Returns the first child DOM element under the specified DOM node that matches the specified namespace URI and local name.
 * @param domNode - DOM node from which the child DOM element is going to be retrieved.
 * @param {String} [namespaceURI] - 
 * @param {String} [localName] - 
 * @return The node's first child DOM element that matches the specified namespace URI and local name; null otherwise.</returns>
 */
function xmlFirstChildElement(domNode, namespaceURI, localName) {

    return xmlFirstElementMaybeRecursive(domNode, namespaceURI, localName, /*recursive*/false);
}

/** Returns the first descendant DOM element under the specified DOM node that matches the specified namespace URI and local name.
 * @param domNode - DOM node from which the descendant DOM element is going to be retrieved.
 * @param {String} [namespaceURI] - 
 * @param {String} [localName] - 
 * @return The node's first descendant DOM element that matches the specified namespace URI and local name; null otherwise.
*/
function xmlFirstDescendantElement(domNode, namespaceURI, localName) {
    if (domNode.getElementsByTagNameNS) {
        var result = domNode.getElementsByTagNameNS(namespaceURI, localName);
        return result.length > 0 ? result[0] : null;
    }
    return xmlFirstElementMaybeRecursive(domNode, namespaceURI, localName, /*recursive*/true);
}

/** Returns the first descendant DOM element under the specified DOM node that matches the specified namespace URI and local name.
 * @param domNode - DOM node from which the descendant DOM element is going to be retrieved.
 * @param {String} [namespaceURI] - 
 * @param {String} [localName] - 
 * @param {Boolean} recursive 
 * - True if the search should include all the descendants of the DOM node.  
 * - False if the search should be scoped only to the direct children of the DOM node.
 * @return The node's first descendant DOM element that matches the specified namespace URI and local name; null otherwise.
 */
function xmlFirstElementMaybeRecursive(domNode, namespaceURI, localName, recursive) {

    var firstElement = null;
    xmlTraverse(domNode, recursive, function (child) {
        if (child.nodeType === 1) {
            var isExpectedNamespace = !namespaceURI || xmlNamespaceURI(child) === namespaceURI;
            var isExpectedNodeName = !localName || xmlLocalName(child) === localName;

            if (isExpectedNamespace && isExpectedNodeName) {
                firstElement = child;
            }
        }
        return firstElement === null;
    });
    return firstElement;
}

/** Gets the concatenated value of all immediate child text and CDATA nodes for the specified element.
 * @param domElement - Element to get values for.
 * @returns {String} Text for all direct children.
 */
function xmlInnerText(xmlElement) {

    var result = null;
    var root = (xmlElement.nodeType === 9 && xmlElement.documentElement) ? xmlElement.documentElement : xmlElement;
    var whitespaceAlreadyRemoved = root.ownerDocument.preserveWhiteSpace === false;
    var whitespacePreserveContext;

    xmlTraverse(root, false, function (child) {
        if (child.nodeType === 3 || child.nodeType === 4) {
            // isElementContentWhitespace indicates that this is 'ignorable whitespace',
            // but it's not defined by all browsers, and does not honor xml:space='preserve'
            // in some implementations.
            //
            // If we can't tell either way, we walk up the tree to figure out whether
            // xml:space is set to preserve; otherwise we discard pure-whitespace.
            //
            // For example <a>  <b>1</b></a>. The space between <a> and <b> is usually 'ignorable'.
            var text = xmlNodeValue(child);
            var shouldInclude = whitespaceAlreadyRemoved || !isWhitespace(text);
            if (!shouldInclude) {
                // Walk up the tree to figure out whether we are in xml:space='preserve' context
                // for the cursor (needs to happen only once).
                if (whitespacePreserveContext === undefined) {
                    whitespacePreserveContext = isWhitespacePreserveContext(root);
                }

                shouldInclude = whitespacePreserveContext;
            }

            if (shouldInclude) {
                if (!result) {
                    result = text;
                } else {
                    result += text;
                }
            }
        }
        // Continue traversing?
        return true;
    });
    return result;
}

/** Returns the localName of a XML node.
 * @param domNode - DOM node to get the value from.
 * @returns {String} localName of domNode.
 */
function xmlLocalName(domNode) {

    return domNode.localName || domNode.baseName;
}

/** Returns the namespace URI of a XML node.
 * @param node - DOM node to get the value from.
 * @returns {String} Namespace URI of domNode.
 */
function xmlNamespaceURI(domNode) {

    return domNode.namespaceURI || null;
}

/** Returns the value or the inner text of a XML node.
 * @param node - DOM node to get the value from.
 * @return Value of the domNode or the inner text if domNode represents a DOM element node.
 */
function xmlNodeValue(domNode) {
    
    if (domNode.nodeType === 1) {
        return xmlInnerText(domNode);
    }
    return domNode.nodeValue;
}

/** Walks through the descendants of the domNode and invokes a callback for each node.
 * @param domNode - DOM node whose descendants are going to be traversed.
 * @param {Boolean} recursive
 * - True if the traversal should include all the descenants of the DOM node.
 * - False if the traversal should be scoped only to the direct children of the DOM node.
 * @returns {String} Namespace URI of node.
 */
function xmlTraverse(domNode, recursive, onChildCallback) {

    var subtrees = [];
    var child = domNode.firstChild;
    var proceed = true;
    while (child && proceed) {
        proceed = onChildCallback(child);
        if (proceed) {
            if (recursive && child.firstChild) {
                subtrees.push(child.firstChild);
            }
            child = child.nextSibling || subtrees.shift();
        }
    }
}

/** Returns the next sibling DOM element of the specified DOM node.
 * @param domNode - DOM node from which the next sibling is going to be retrieved.
 * @param {String} [namespaceURI] - 
 * @param {String} [localName] - 
 * @return The node's next sibling DOM element, null if there is none.</returns>
 */
function xmlSiblingElement(domNode, namespaceURI, localName) {

    var sibling = domNode.nextSibling;
    while (sibling) {
        if (sibling.nodeType === 1) {
            var isExpectedNamespace = !namespaceURI || xmlNamespaceURI(sibling) === namespaceURI;
            var isExpectedNodeName = !localName || xmlLocalName(sibling) === localName;

            if (isExpectedNamespace && isExpectedNodeName) {
                return sibling;
            }
        }
        sibling = sibling.nextSibling;
    }
    return null;
}

/** Creates a new empty DOM document node.
 * @return New DOM document node.</returns>
 *
 * This function will first try to create a native DOM document using
 * the browsers createDocument function.  If the browser doesn't
 * support this but supports ActiveXObject, then an attempt to create
 * an MSXML 6.0 DOM will be made. If this attempt fails too, then an attempt
 * for creating an MXSML 3.0 DOM will be made.  If this last attemp fails or
 * the browser doesn't support ActiveXObject then an exception will be thrown.
 */
function xmlDom() {
    var implementation = window.document.implementation;
    return (implementation && implementation.createDocument) ?
       implementation.createDocument(null, null, null) :
       msXmlDom();
}

/** Appends a collection of child nodes or string values to a parent DOM node.
 * @param parent - DOM node to which the children will be appended.
 * @param {Array} children - Array containing DOM nodes or string values that will be appended to the parent.
 * @return The parent with the appended children or string values.</returns>
 *  If a value in the children collection is a string, then a new DOM text node is going to be created
 *  for it and then appended to the parent.
 */
function xmlAppendChildren(parent, children) {
    if (!isArray(children)) {
        return xmlAppendChild(parent, children);
    }

    var i, len;
    for (i = 0, len = children.length; i < len; i++) {
        children[i] && xmlAppendChild(parent, children[i]);
    }
    return parent;
}

/** Appends a child node or a string value to a parent DOM node.
 * @param parent - DOM node to which the child will be appended.
 * @param child - Child DOM node or string value to append to the parent.
 * @return The parent with the appended child or string value.</returns>
 * If child is a string value, then a new DOM text node is going to be created
 * for it and then appended to the parent.
 */
function xmlAppendChild(parent, child) {

    djsassert(parent !== child, "xmlAppendChild() - parent and child are one and the same!");
    if (child) {
        if (typeof child === "string") {
            return xmlAppendText(parent, xmlNewText(parent.ownerDocument, child));
        }
        if (child.nodeType === 2) {
            parent.setAttributeNodeNS ? parent.setAttributeNodeNS(child) : parent.setAttributeNode(child);
        } else {
            parent.appendChild(child);
        }
    }
    return parent;
}

/** Creates a new DOM attribute node.
 * @param dom - DOM document used to create the attribute.
 * @param {String} prefix - Namespace prefix.
 * @param {String} namespaceURI - Namespace URI.
 * @return DOM attribute node for the namespace declaration.
 */
function xmlNewAttribute(dom, namespaceURI, qualifiedName, value) {

    var attribute =
        dom.createAttributeNS && dom.createAttributeNS(namespaceURI, qualifiedName) ||
        dom.createNode(2, qualifiedName, namespaceURI || undefined);

    attribute.value = value || "";
    return attribute;
}

/** Creates a new DOM element node.
 * @param dom - DOM document used to create the DOM element.
 * @param {String} namespaceURI - Namespace URI of the new DOM element.
 * @param {String} qualifiedName - Qualified name in the form of "prefix:name" of the new DOM element.
 * @param {Array} [children] Collection of child DOM nodes or string values that are going to be appended to the new DOM element.
 * @return New DOM element.</returns>
 * If a value in the children collection is a string, then a new DOM text node is going to be created
 * for it and then appended to the new DOM element.
 */
function xmlNewElement(dom, nampespaceURI, qualifiedName, children) {
    var element =
        dom.createElementNS && dom.createElementNS(nampespaceURI, qualifiedName) ||
        dom.createNode(1, qualifiedName, nampespaceURI || undefined);

    return xmlAppendChildren(element, children || []);
}

/** Creates a namespace declaration attribute.
 * @param dom - DOM document used to create the attribute.
 * @param {String} namespaceURI - Namespace URI.
 * @param {String} prefix - Namespace prefix.
 * @return DOM attribute node for the namespace declaration.</returns>
 */
function xmlNewNSDeclaration(dom, namespaceURI, prefix) {
    return xmlNewAttribute(dom, xmlnsNS, xmlQualifiedName("xmlns", prefix), namespaceURI);
}

/** Creates a new DOM document fragment node for the specified xml text.
 * @param dom - DOM document from which the fragment node is going to be created.
 * @param {String} text XML text to be represented by the XmlFragment.
 * @return New DOM document fragment object.
 */
function xmlNewFragment(dom, text) {

    var value = "<c>" + text + "</c>";
    var tempDom = xmlParse(value);
    var tempRoot = tempDom.documentElement;
    var imported = ("importNode" in dom) ? dom.importNode(tempRoot, true) : tempRoot;
    var fragment = dom.createDocumentFragment();

    var importedChild = imported.firstChild;
    while (importedChild) {
        fragment.appendChild(importedChild);
        importedChild = importedChild.nextSibling;
    }
    return fragment;
}

/** Creates new DOM text node.
 * @param dom - DOM document used to create the text node.
 * @param {String} text - Text value for the DOM text node.
 * @return DOM text node.</returns>
 */ 
function xmlNewText(dom, text) {
    return dom.createTextNode(text);
}

/** Creates a new DOM element or DOM attribute node as specified by path and appends it to the DOM tree pointed by root.
 * @param dom - DOM document used to create the new node.
 * @param root - DOM element node used as root of the subtree on which the new nodes are going to be created.
 * @param {String} namespaceURI - Namespace URI of the new DOM element or attribute.
 * @param {String} namespacePrefix - Prefix used to qualify the name of the new DOM element or attribute.
 * @param {String} Path - Path string describing the location of the new DOM element or attribute from the root element.
 * @return DOM element or attribute node for the last segment of the path.</returns>

 * This function will traverse the path and will create a new DOM element with the specified namespace URI and prefix
 * for each segment that doesn't have a matching element under root.
 * The last segment of the path may be decorated with a starting @ character. In this case a new DOM attribute node
 * will be created.
 */
function xmlNewNodeByPath(dom, root, namespaceURI, prefix, path) {
    var name = "";
    var parts = path.split("/");
    var xmlFindNode = xmlFirstChildElement;
    var xmlNewNode = xmlNewElement;
    var xmlNode = root;

    var i, len;
    for (i = 0, len = parts.length; i < len; i++) {
        name = parts[i];
        if (name.charAt(0) === "@") {
            name = name.substring(1);
            xmlFindNode = xmlAttributeNode;
            xmlNewNode = xmlNewAttribute;
        }

        var childNode = xmlFindNode(xmlNode, namespaceURI, name);
        if (!childNode) {
            childNode = xmlNewNode(dom, namespaceURI, xmlQualifiedName(prefix, name));
            xmlAppendChild(xmlNode, childNode);
        }
        xmlNode = childNode;
    }
    return xmlNode;
}

/** Returns the text representation of the document to which the specified node belongs.
 * @param root - Wrapped element in the document to serialize.
 * @returns {String} Serialized document.
*/
function xmlSerialize(domNode) {
    var xmlSerializer = window.XMLSerializer;
    if (xmlSerializer) {
        var serializer = new xmlSerializer();
        return serializer.serializeToString(domNode);
    }

    if (domNode.xml) {
        return domNode.xml;
    }

    throw { message: "XML serialization unsupported" };
}

/** Returns the XML representation of the all the descendants of the node.
 * @param domNode - Node to serialize.</param>
 * @returns {String} The XML representation of all the descendants of the node.
 */
function xmlSerializeDescendants(domNode) {
    var children = domNode.childNodes;
    var i, len = children.length;
    if (len === 0) {
        return "";
    }

    // Some implementations of the XMLSerializer don't deal very well with fragments that
    // don't have a DOMElement as their first child. The work around is to wrap all the
    // nodes in a dummy root node named "c", serialize it and then just extract the text between
    // the <c> and the </c> substrings.

    var dom = domNode.ownerDocument;
    var fragment = dom.createDocumentFragment();
    var fragmentRoot = dom.createElement("c");

    fragment.appendChild(fragmentRoot);
    // Move the children to the fragment tree.
    for (i = 0; i < len; i++) {
        fragmentRoot.appendChild(children[i]);
    }

    var xml = xmlSerialize(fragment);
    xml = xml.substr(3, xml.length - 7);

    // Move the children back to the original dom tree.
    for (i = 0; i < len; i++) {
        domNode.appendChild(fragmentRoot.childNodes[i]);
    }

    return xml;
}

/** Returns the XML representation of the node and all its descendants.
 * @param domNode - Node to serialize
 * @returns {String} The XML representation of the node and all its descendants.
 */
function xmlSerializeNode(domNode) {

    var xml = domNode.xml;
    if (xml !== undefined) {
        return xml;
    }

    if (window.XMLSerializer) {
        var serializer = new window.XMLSerializer();
        return serializer.serializeToString(domNode);
    }

    throw { message: "XML serialization unsupported" };
}

exports.http = http;
exports.w3org = w3org;
exports.xmlNS = xmlNS;
exports.xmlnsNS = xmlnsNS;

exports.hasLeadingOrTrailingWhitespace = hasLeadingOrTrailingWhitespace;
exports.isXmlNSDeclaration = isXmlNSDeclaration;
exports.xmlAppendChild = xmlAppendChild;
exports.xmlAppendChildren = xmlAppendChildren;
exports.xmlAttributeNode = xmlAttributeNode;
exports.xmlAttributes = xmlAttributes;
exports.xmlAttributeValue = xmlAttributeValue;
exports.xmlBaseURI = xmlBaseURI;
exports.xmlChildElements = xmlChildElements;
exports.xmlFindElementByPath = xmlFindElementByPath;
exports.xmlFindNodeByPath = xmlFindNodeByPath;
exports.xmlFirstChildElement = xmlFirstChildElement;
exports.xmlFirstDescendantElement = xmlFirstDescendantElement;
exports.xmlInnerText = xmlInnerText;
exports.xmlLocalName = xmlLocalName;
exports.xmlNamespaceURI = xmlNamespaceURI;
exports.xmlNodeValue = xmlNodeValue;
exports.xmlDom = xmlDom;
exports.xmlNewAttribute = xmlNewAttribute;
exports.xmlNewElement = xmlNewElement;
exports.xmlNewFragment = xmlNewFragment;
exports.xmlNewNodeByPath = xmlNewNodeByPath;
exports.xmlNewNSDeclaration = xmlNewNSDeclaration;
exports.xmlNewText = xmlNewText;
exports.xmlParse = xmlParse;
exports.xmlQualifiedName = xmlQualifiedName;
exports.xmlSerialize = xmlSerialize;
exports.xmlSerializeDescendants = xmlSerializeDescendants;
exports.xmlSiblingElement = xmlSiblingElement;
