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 < 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;
+ <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 < 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 < 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 <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 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 < 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 = "<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.
+ */
+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 < 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 <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;
</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>