You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@olingo.apache.org by bu...@apache.org on 2015/04/09 11:03:53 UTC

svn commit: r946869 [16/16] - in /websites/staging/olingo/trunk/content: ./ doc/javascript/apidoc/

Modified: websites/staging/olingo/trunk/content/doc/javascript/apidoc/xml.js.html
==============================================================================
--- websites/staging/olingo/trunk/content/doc/javascript/apidoc/xml.js.html (original)
+++ websites/staging/olingo/trunk/content/doc/javascript/apidoc/xml.js.html Thu Apr  9 09:03:51 2015
@@ -2,7 +2,7 @@
 <html lang="en">
 <head>
     <meta charset="utf-8">
-    <title>JSDoc: Source: odatajs/xml.js</title>
+    <title>JSDoc: Source: xml.js</title>
     
     <script src="scripts/prettify/prettify.js"> </script>
     <script src="scripts/prettify/lang-css.js"> </script>
@@ -17,7 +17,7 @@
 
 <div id="main">
     
-    <h1 class="page-title">Source: odatajs/xml.js</h1>
+    <h1 class="page-title">Source: xml.js</h1>
     
     
 
@@ -25,822 +25,830 @@
     
     <section>
         <article>
-            <pre class="prettyprint source"><code>/*
- * 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 &lt; 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 &lt; 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.&lt;/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.&lt;/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 &lt;a>  &lt;b>1&lt;/b>&lt;/a>. The space between &lt;a> and &lt;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.&lt;/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.&lt;/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.&lt;/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 &lt; 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.&lt;/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.&lt;/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.&lt;/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 = "&lt;c>" + text + "&lt;/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.&lt;/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.&lt;/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 &lt; 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.&lt;/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 &lt;c> and the &lt;/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 &lt; 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 &lt; 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;
+            <pre class="prettyprint source"><code>/*
+ * 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.
+ */
+'use strict';
+ 
+
+/** @module odatajs/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 = undefined;
+    if (utils.inBrowser()) {
+        domParser = window.DOMParser && new window.DOMParser();
+    } else {
+        domParser = new (require('xmldom').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} textNode - 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 &lt; 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 domNode - 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 &lt; 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.
+
+* 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.
+ */
+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 xmlElement - 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 &lt;a>  &lt;b>1&lt;/b>&lt;/a>. The space between &lt;a> and &lt;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 domNode - 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 domNode - 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.
+ * @param {Boolean} onChildCallback - Called for each child
+ * @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.
+ */
+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.
+ *
+ * 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.
+ *  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 &lt; 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.
+ * 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} namespaceURI - Namespace URI.
+ * @param {String} qualifiedName - Qualified OData name
+ * @param {String} value - Value of the new attribute
+ * @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.
+ * 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, namespaceURI, 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.
+ */
+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 = "&lt;c>" + text + "&lt;/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.
+ */ 
+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} prefix - 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.
+
+ * 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 &lt; 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 domNode - 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.
+ * @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 &lt;c> and the &lt;/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 &lt; 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 &lt; 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;
 </code></pre>
         </article>
     </section>
@@ -851,13 +859,13 @@ exports.xmlSiblingElement = xmlSiblingEl
 </div>
 
 <nav>
-    <h2><a href="index.html">Index</a></h2><h3>Modules</h3><ul><li><a href="module-cache.html">cache</a></li><li><a href="source.html">cache/source</a></li><li><a href="module-datajs.html">datajs</a></li><li><a href="deferred.html">datajs/deferred</a></li><li><a href="utils.html">datajs/utils</a></li><li><a href="xml.html">datajs/xml</a></li><li><a href="module-odata.html">odata</a></li><li><a href="batch.html">odata/batch</a></li><li><a href="handler.html">odata/handler</a></li><li><a href="json.html">odata/json</a></li><li><a href="metadata.html">odata/metadata</a></li><li><a href="net.html">odata/net</a></li><li><a href="utils_.html">odata/utils</a></li><li><a href="module-store.html">store</a></li><li><a href="dom.html">store/dom</a></li><li><a href="indexeddb.html">store/indexeddb</a></li><li><a href="memory.html">store/memory</a></li></ul><h3>Classes</h3><ul><li><a href="DataCache.html">DataCache</a></li><li><a href="DataCacheOperation.html">DataCacheOperation</a></li><li><a h
 ref="DjsDeferred.html">DjsDeferred</a></li><li><a href="dom-DomStore.html">DomStore</a></li><li><a href="indexeddb-IndexedDBStore.html">IndexedDBStore</a></li><li><a href="memory-MemoryStore.html">MemoryStore</a></li><li><a href="ODataCacheSource.html">ODataCacheSource</a></li></ul><h3><a href="global.html">Global</a></h3>
+    <h2><a href="index.html">Index</a></h2><h3>Modules</h3><ul><li><a href="module-cache.html">cache</a></li><li><a href="source.html">cache/source</a></li><li><a href="module-odata.html">odata</a></li><li><a href="batch.html">odata/batch</a></li><li><a href="handler.html">odata/handler</a></li><li><a href="json.html">odata/json</a></li><li><a href="metadata.html">odata/metadata</a></li><li><a href="net.html">odata/net</a></li><li><a href="utils.html">odata/utils</a></li><li><a href="deferred.html">odatajs/deferred</a></li><li><a href="utils_.html">odatajs/utils</a></li><li><a href="xml.html">odatajs/xml</a></li><li><a href="module-store.html">store</a></li><li><a href="dom.html">store/dom</a></li><li><a href="indexeddb.html">store/indexeddb</a></li><li><a href="memory.html">store/memory</a></li></ul><h3>Classes</h3><ul><li><a href="DataCache.html">DataCache</a></li><li><a href="DataCacheOperation.html">DataCacheOperation</a></li><li><a href="DjsDeferred.html">DjsDeferred</a></li><l
 i><a href="dom-DomStore.html">DomStore</a></li><li><a href="indexeddb-IndexedDBStore.html">IndexedDBStore</a></li><li><a href="memory-MemoryStore.html">MemoryStore</a></li><li><a href="ODataCacheSource.html">ODataCacheSource</a></li></ul><h3><a href="global.html">Global</a></h3>
 </nav>
 
 <br clear="both">
 
 <footer>
-    Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.2.2</a> on Mon Sep 15 2014 13:07:59 GMT+0200 (MESZ)
+    Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.2.2</a> on Thu Apr 09 2015 08:31:26 GMT+0200 (MESZ)
 </footer>
 
 <script> prettyPrint(); </script>