| <!DOCTYPE html> |
| <html lang="en"> |
| <head> |
| <meta charset="utf-8"> |
| <title>JSDoc: Source: xml.js</title> |
| |
| <script src="scripts/prettify/prettify.js"> </script> |
| <script src="scripts/prettify/lang-css.js"> </script> |
| <!--[if lt IE 9]> |
| <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script> |
| <![endif]--> |
| <link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css"> |
| <link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css"> |
| </head> |
| |
| <body> |
| |
| <div id="main"> |
| |
| <h1 class="page-title">Source: xml.js</h1> |
| |
| |
| |
| |
| |
| <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.
|
| */
|
| '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> |
| |
| |
| |
| |
| </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-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><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> |
| </nav> |
| |
| <br clear="both"> |
| |
| <footer> |
| 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> |
| <script src="scripts/linenumber.js"> </script> |
| </body> |
| </html> |