<!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> | |
<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> |