|
/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for |
|
* full list of contributors). Published under the Clear BSD license. |
|
* See http://svn.openlayers.org/trunk/openlayers/license.txt for the |
|
* full text of the license. */ |
|
|
|
/** |
|
* @requires OpenLayers/Format.js |
|
*/ |
|
|
|
/** |
|
* Class: OpenLayers.Format.XML |
|
* Read and write XML. For cross-browser XML generation, use methods on an |
|
* instance of the XML format class instead of on <code>document<end>. |
|
* The DOM creation and traversing methods exposed here all mimic the |
|
* W3C XML DOM methods. Create a new parser with the |
|
* <OpenLayers.Format.XML> constructor. |
|
* |
|
* Inherits from: |
|
* - <OpenLayers.Format> |
|
*/ |
|
OpenLayers.Format.XML = OpenLayers.Class(OpenLayers.Format, { |
|
|
|
/** |
|
* Property: namespaces |
|
* {Object} Mapping of namespace aliases to namespace URIs. Properties |
|
* of this object should not be set individually. Read-only. All |
|
* XML subclasses should have their own namespaces object. Use |
|
* <setNamespace> to add or set a namespace alias after construction. |
|
*/ |
|
namespaces: null, |
|
|
|
/** |
|
* Property: namespaceAlias |
|
* {Object} Mapping of namespace URI to namespace alias. This object |
|
* is read-only. Use <setNamespace> to add or set a namespace alias. |
|
*/ |
|
namespaceAlias: null, |
|
|
|
/** |
|
* Property: defaultPrefix |
|
* {String} The default namespace alias for creating element nodes. |
|
*/ |
|
defaultPrefix: null, |
|
|
|
/** |
|
* Property: readers |
|
* Contains public functions, grouped by namespace prefix, that will |
|
* be applied when a namespaced node is found matching the function |
|
* name. The function will be applied in the scope of this parser |
|
* with two arguments: the node being read and a context object passed |
|
* from the parent. |
|
*/ |
|
readers: {}, |
|
|
|
/** |
|
* Property: writers |
|
* As a compliment to the <readers> property, this structure contains public |
|
* writing functions grouped by namespace alias and named like the |
|
* node names they produce. |
|
*/ |
|
writers: {}, |
|
|
|
/** |
|
* Property: xmldom |
|
* {XMLDom} If this browser uses ActiveX, this will be set to a XMLDOM |
|
* object. It is not intended to be a browser sniffing property. |
|
* Instead, the xmldom property is used instead of <code>document<end> |
|
* where namespaced node creation methods are not supported. In all |
|
* other browsers, this remains null. |
|
*/ |
|
xmldom: null, |
|
|
|
/** |
|
* Constructor: OpenLayers.Format.XML |
|
* Construct an XML parser. The parser is used to read and write XML. |
|
* Reading XML from a string returns a DOM element. Writing XML from |
|
* a DOM element returns a string. |
|
* |
|
* Parameters: |
|
* options - {Object} Optional object whose properties will be set on |
|
* the object. |
|
*/ |
|
initialize: function(options) { |
|
if(window.ActiveXObject) { |
|
this.xmldom = new ActiveXObject("Microsoft.XMLDOM"); |
|
} |
|
OpenLayers.Format.prototype.initialize.apply(this, [options]); |
|
// clone the namespace object and set all namespace aliases |
|
this.namespaces = OpenLayers.Util.extend({}, this.namespaces); |
|
this.namespaceAlias = {}; |
|
for(var alias in this.namespaces) { |
|
this.namespaceAlias[this.namespaces[alias]] = alias; |
|
} |
|
}, |
|
|
|
/** |
|
* APIMethod: destroy |
|
* Clean up. |
|
*/ |
|
destroy: function() { |
|
this.xmldom = null; |
|
OpenLayers.Format.prototype.destroy.apply(this, arguments); |
|
}, |
|
|
|
/** |
|
* Method: setNamespace |
|
* Set a namespace alias and URI for the format. |
|
* |
|
* Parameters: |
|
* alias - {String} The namespace alias (prefix). |
|
* uri - {String} The namespace URI. |
|
*/ |
|
setNamespace: function(alias, uri) { |
|
this.namespaces[alias] = uri; |
|
this.namespaceAlias[uri] = alias; |
|
}, |
|
|
|
/** |
|
* APIMethod: read |
|
* Deserialize a XML string and return a DOM node. |
|
* |
|
* Parameters: |
|
* text - {String} A XML string |
|
|
|
* Returns: |
|
* {DOMElement} A DOM node |
|
*/ |
|
read: function(text) { |
|
var index = text.indexOf('<'); |
|
if(index > 0) { |
|
text = text.substring(index); |
|
} |
|
var node = OpenLayers.Util.Try( |
|
OpenLayers.Function.bind(( |
|
function() { |
|
var xmldom; |
|
/** |
|
* Since we want to be able to call this method on the prototype |
|
* itself, this.xmldom may not exist even if in IE. |
|
*/ |
|
if(window.ActiveXObject && !this.xmldom) { |
|
xmldom = new ActiveXObject("Microsoft.XMLDOM"); |
|
} else { |
|
xmldom = this.xmldom; |
|
|
|
} |
|
xmldom.loadXML(text); |
|
return xmldom; |
|
} |
|
), this), |
|
function() { |
|
return new DOMParser().parseFromString(text, 'text/xml'); |
|
}, |
|
function() { |
|
var req = new XMLHttpRequest(); |
|
req.open("GET", "data:" + "text/xml" + |
|
";charset=utf-8," + encodeURIComponent(text), false); |
|
if(req.overrideMimeType) { |
|
req.overrideMimeType("text/xml"); |
|
} |
|
req.send(null); |
|
return req.responseXML; |
|
} |
|
); |
|
|
|
if(this.keepData) { |
|
this.data = node; |
|
} |
|
|
|
return node; |
|
}, |
|
|
|
/** |
|
* APIMethod: write |
|
* Serialize a DOM node into a XML string. |
|
* |
|
* Parameters: |
|
* node - {DOMElement} A DOM node. |
|
* |
|
* Returns: |
|
* {String} The XML string representation of the input node. |
|
*/ |
|
write: function(node) { |
|
var data; |
|
if(this.xmldom) { |
|
data = node.xml; |
|
} else { |
|
var serializer = new XMLSerializer(); |
|
if (node.nodeType == 1) { |
|
// Add nodes to a document before serializing. Everything else |
|
// is serialized as is. This may need more work. See #1218 . |
|
var doc = document.implementation.createDocument("", "", null); |
|
if (doc.importNode) { |
|
node = doc.importNode(node, true); |
|
} |
|
doc.appendChild(node); |
|
data = serializer.serializeToString(doc); |
|
} else { |
|
data = serializer.serializeToString(node); |
|
} |
|
} |
|
return data; |
|
}, |
|
|
|
/** |
|
* APIMethod: createElementNS |
|
* Create a new element with namespace. This node can be appended to |
|
* another node with the standard node.appendChild method. For |
|
* cross-browser support, this method must be used instead of |
|
* document.createElementNS. |
|
* |
|
* Parameters: |
|
* uri - {String} Namespace URI for the element. |
|
* name - {String} The qualified name of the element (prefix:localname). |
|
* |
|
* Returns: |
|
* {Element} A DOM element with namespace. |
|
*/ |
|
createElementNS: function(uri, name) { |
|
var element; |
|
if(this.xmldom) { |
|
if(typeof uri == "string") { |
|
element = this.xmldom.createNode(1, name, uri); |
|
} else { |
|
element = this.xmldom.createNode(1, name, ""); |
|
} |
|
} else { |
|
element = document.createElementNS(uri, name); |
|
} |
|
return element; |
|
}, |
|
|
|
/** |
|
* APIMethod: createTextNode |
|
* Create a text node. This node can be appended to another node with |
|
* the standard node.appendChild method. For cross-browser support, |
|
* this method must be used instead of document.createTextNode. |
|
* |
|
* Parameters: |
|
* text - {String} The text of the node. |
|
* |
|
* Returns: |
|
* {DOMElement} A DOM text node. |
|
*/ |
|
createTextNode: function(text) { |
|
var node; |
|
if (typeof text !== "string") { |
|
text = String(text); |
|
} |
|
if(this.xmldom) { |
|
node = this.xmldom.createTextNode(text); |
|
} else { |
|
node = document.createTextNode(text); |
|
} |
|
return node; |
|
}, |
|
|
|
/** |
|
* APIMethod: getElementsByTagNameNS |
|
* Get a list of elements on a node given the namespace URI and local name. |
|
* To return all nodes in a given namespace, use '*' for the name |
|
* argument. To return all nodes of a given (local) name, regardless |
|
* of namespace, use '*' for the uri argument. |
|
* |
|
* Parameters: |
|
* node - {Element} Node on which to search for other nodes. |
|
* uri - {String} Namespace URI. |
|
* name - {String} Local name of the tag (without the prefix). |
|
* |
|
* Returns: |
|
* {NodeList} A node list or array of elements. |
|
*/ |
|
getElementsByTagNameNS: function(node, uri, name) { |
|
var elements = []; |
|
if(node.getElementsByTagNameNS) { |
|
elements = node.getElementsByTagNameNS(uri, name); |
|
} else { |
|
// brute force method |
|
var allNodes = node.getElementsByTagName("*"); |
|
var potentialNode, fullName; |
|
for(var i=0, len=allNodes.length; i<len; ++i) { |
|
potentialNode = allNodes[i]; |
|
fullName = (potentialNode.prefix) ? |
|
(potentialNode.prefix + ":" + name) : name; |
|
if((name == "*") || (fullName == potentialNode.nodeName)) { |
|
if((uri == "*") || (uri == potentialNode.namespaceURI)) { |
|
elements.push(potentialNode); |
|
} |
|
} |
|
} |
|
} |
|
return elements; |
|
}, |
|
|
|
/** |
|
* APIMethod: getAttributeNodeNS |
|
* Get an attribute node given the namespace URI and local name. |
|
* |
|
* Parameters: |
|
* node - {Element} Node on which to search for attribute nodes. |
|
* uri - {String} Namespace URI. |
|
* name - {String} Local name of the attribute (without the prefix). |
|
* |
|
* Returns: |
|
* {DOMElement} An attribute node or null if none found. |
|
*/ |
|
getAttributeNodeNS: function(node, uri, name) { |
|
var attributeNode = null; |
|
if(node.getAttributeNodeNS) { |
|
attributeNode = node.getAttributeNodeNS(uri, name); |
|
} else { |
|
var attributes = node.attributes; |
|
var potentialNode, fullName; |
|
for(var i=0, len=attributes.length; i<len; ++i) { |
|
potentialNode = attributes[i]; |
|
if(potentialNode.namespaceURI == uri) { |
|
fullName = (potentialNode.prefix) ? |
|
(potentialNode.prefix + ":" + name) : name; |
|
if(fullName == potentialNode.nodeName) { |
|
attributeNode = potentialNode; |
|
break; |
|
} |
|
} |
|
} |
|
} |
|
return attributeNode; |
|
}, |
|
|
|
/** |
|
* APIMethod: getAttributeNS |
|
* Get an attribute value given the namespace URI and local name. |
|
* |
|
* Parameters: |
|
* node - {Element} Node on which to search for an attribute. |
|
* uri - {String} Namespace URI. |
|
* name - {String} Local name of the attribute (without the prefix). |
|
* |
|
* Returns: |
|
* {String} An attribute value or and empty string if none found. |
|
*/ |
|
getAttributeNS: function(node, uri, name) { |
|
var attributeValue = ""; |
|
if(node.getAttributeNS) { |
|
attributeValue = node.getAttributeNS(uri, name) || ""; |
|
} else { |
|
var attributeNode = this.getAttributeNodeNS(node, uri, name); |
|
if(attributeNode) { |
|
attributeValue = attributeNode.nodeValue; |
|
} |
|
} |
|
return attributeValue; |
|
}, |
|
|
|
/** |
|
* APIMethod: getChildValue |
|
* Get the textual value of the node if it exists, or return an |
|
* optional default string. Returns an empty string if no first child |
|
* exists and no default value is supplied. |
|
* |
|
* Parameters: |
|
* node - {DOMElement} The element used to look for a first child value. |
|
* def - {String} Optional string to return in the event that no |
|
* first child value exists. |
|
* |
|
* Returns: |
|
* {String} The value of the first child of the given node. |
|
*/ |
|
getChildValue: function(node, def) { |
|
var value = def || ""; |
|
if(node) { |
|
for(var child=node.firstChild; child; child=child.nextSibling) { |
|
switch(child.nodeType) { |
|
case 3: // text node |
|
case 4: // cdata section |
|
value += child.nodeValue; |
|
} |
|
} |
|
} |
|
return value; |
|
}, |
|
|
|
/** |
|
* APIMethod: concatChildValues |
|
* *Deprecated*. Use <getChildValue> instead. |
|
* |
|
* Concatenate the value of all child nodes if any exist, or return an |
|
* optional default string. Returns an empty string if no children |
|
* exist and no default value is supplied. Not optimized for large |
|
* numbers of child nodes. |
|
* |
|
* Parameters: |
|
* node - {DOMElement} The element used to look for child values. |
|
* def - {String} Optional string to return in the event that no |
|
* child exist. |
|
* |
|
* Returns: |
|
* {String} The concatenated value of all child nodes of the given node. |
|
*/ |
|
concatChildValues: function(node, def) { |
|
var value = ""; |
|
var child = node.firstChild; |
|
var childValue; |
|
while(child) { |
|
childValue = child.nodeValue; |
|
if(childValue) { |
|
value += childValue; |
|
} |
|
child = child.nextSibling; |
|
} |
|
if(value == "" && def != undefined) { |
|
value = def; |
|
} |
|
return value; |
|
}, |
|
|
|
/** |
|
* APIMethod: isSimpleContent |
|
* Test if the given node has only simple content (i.e. no child element |
|
* nodes). |
|
* |
|
* Parameters: |
|
* node - {DOMElement} An element node. |
|
* |
|
* Returns: |
|
* {Boolean} The node has no child element nodes (nodes of type 1). |
|
*/ |
|
isSimpleContent: function(node) { |
|
var simple = true; |
|
for(var child=node.firstChild; child; child=child.nextSibling) { |
|
if(child.nodeType === 1) { |
|
simple = false; |
|
break; |
|
} |
|
} |
|
return simple; |
|
}, |
|
|
|
/** |
|
* APIMethod: contentType |
|
* Determine the content type for a given node. |
|
* |
|
* Parameters: |
|
* node - {DOMElement} |
|
* |
|
* Returns: |
|
* {Integer} One of OpenLayers.Format.XML.CONTENT_TYPE.{EMPTY,SIMPLE,COMPLEX,MIXED} |
|
* if the node has no, simple, complex, or mixed content. |
|
*/ |
|
contentType: function(node) { |
|
var simple = false, |
|
complex = false; |
|
|
|
var type = OpenLayers.Format.XML.CONTENT_TYPE.EMPTY; |
|
|
|
for(var child=node.firstChild; child; child=child.nextSibling) { |
|
switch(child.nodeType) { |
|
case 1: // element |
|
complex = true; |
|
break; |
|
case 8: // comment |
|
break; |
|
default: |
|
simple = true; |
|
} |
|
if(complex && simple) { |
|
break; |
|
} |
|
} |
|
|
|
if(complex && simple) { |
|
type = OpenLayers.Format.XML.CONTENT_TYPE.MIXED; |
|
} else if(complex) { |
|
return OpenLayers.Format.XML.CONTENT_TYPE.COMPLEX; |
|
} else if(simple) { |
|
return OpenLayers.Format.XML.CONTENT_TYPE.SIMPLE; |
|
} |
|
return type; |
|
}, |
|
|
|
/** |
|
* APIMethod: hasAttributeNS |
|
* Determine whether a node has a particular attribute matching the given |
|
* name and namespace. |
|
* |
|
* Parameters: |
|
* node - {Element} Node on which to search for an attribute. |
|
* uri - {String} Namespace URI. |
|
* name - {String} Local name of the attribute (without the prefix). |
|
* |
|
* Returns: |
|
* {Boolean} The node has an attribute matching the name and namespace. |
|
*/ |
|
hasAttributeNS: function(node, uri, name) { |
|
var found = false; |
|
if(node.hasAttributeNS) { |
|
found = node.hasAttributeNS(uri, name); |
|
} else { |
|
found = !!this.getAttributeNodeNS(node, uri, name); |
|
} |
|
return found; |
|
}, |
|
|
|
/** |
|
* APIMethod: setAttributeNS |
|
* Adds a new attribute or changes the value of an attribute with the given |
|
* namespace and name. |
|
* |
|
* Parameters: |
|
* node - {Element} Element node on which to set the attribute. |
|
* uri - {String} Namespace URI for the attribute. |
|
* name - {String} Qualified name (prefix:localname) for the attribute. |
|
* value - {String} Attribute value. |
|
*/ |
|
setAttributeNS: function(node, uri, name, value) { |
|
if(node.setAttributeNS) { |
|
node.setAttributeNS(uri, name, value); |
|
} else { |
|
if(this.xmldom) { |
|
if(uri) { |
|
var attribute = node.ownerDocument.createNode( |
|
2, name, uri |
|
); |
|
attribute.nodeValue = value; |
|
node.setAttributeNode(attribute); |
|
} else { |
|
node.setAttribute(name, value); |
|
} |
|
} else { |
|
throw "setAttributeNS not implemented"; |
|
} |
|
} |
|
}, |
|
|
|
/** |
|
* Method: createElementNSPlus |
|
* Shorthand for creating namespaced elements with optional attributes and |
|
* child text nodes. |
|
* |
|
* Parameters: |
|
* name - {String} The qualified node name. |
|
* options - {Object} Optional object for node configuration. |
|
* |
|
* Valid options: |
|
* uri - {String} Optional namespace uri for the element - supply a prefix |
|
* instead if the namespace uri is a property of the format's namespace |
|
* object. |
|
* attributes - {Object} Optional attributes to be set using the |
|
* <setAttributes> method. |
|
* value - {String} Optional text to be appended as a text node. |
|
* |
|
* Returns: |
|
* {Element} An element node. |
|
*/ |
|
createElementNSPlus: function(name, options) { |
|
options = options || {}; |
|
// order of prefix preference |
|
// 1. in the uri option |
|
// 2. in the prefix option |
|
// 3. in the qualified name |
|
// 4. from the defaultPrefix |
|
var uri = options.uri || this.namespaces[options.prefix]; |
|
if(!uri) { |
|
var loc = name.indexOf(":"); |
|
uri = this.namespaces[name.substring(0, loc)]; |
|
} |
|
if(!uri) { |
|
uri = this.namespaces[this.defaultPrefix]; |
|
} |
|
var node = this.createElementNS(uri, name); |
|
if(options.attributes) { |
|
this.setAttributes(node, options.attributes); |
|
} |
|
var value = options.value; |
|
if(value != null) { |
|
node.appendChild(this.createTextNode(value)); |
|
} |
|
return node; |
|
}, |
|
|
|
/** |
|
* Method: setAttributes |
|
* Set multiple attributes given key value pairs from an object. |
|
* |
|
* Parameters: |
|
* node - {Element} An element node. |
|
* obj - {Object || Array} An object whose properties represent attribute |
|
* names and values represent attribute values. If an attribute name |
|
* is a qualified name ("prefix:local"), the prefix will be looked up |
|
* in the parsers {namespaces} object. If the prefix is found, |
|
* setAttributeNS will be used instead of setAttribute. |
|
*/ |
|
setAttributes: function(node, obj) { |
|
var value, uri; |
|
for(var name in obj) { |
|
if(obj[name] != null && obj[name].toString) { |
|
value = obj[name].toString(); |
|
// check for qualified attribute name ("prefix:local") |
|
uri = this.namespaces[name.substring(0, name.indexOf(":"))] || null; |
|
this.setAttributeNS(node, uri, name, value); |
|
} |
|
} |
|
}, |
|
|
|
/** |
|
* Method: readNode |
|
* Shorthand for applying one of the named readers given the node |
|
* namespace and local name. Readers take two args (node, obj) and |
|
* generally extend or modify the second. |
|
* |
|
* Parameters: |
|
* node - {DOMElement} The node to be read (required). |
|
* obj - {Object} The object to be modified (optional). |
|
* |
|
* Returns: |
|
* {Object} The input object, modified (or a new one if none was provided). |
|
*/ |
|
readNode: function(node, obj) { |
|
if(!obj) { |
|
obj = {}; |
|
} |
|
var group = this.readers[node.namespaceURI ? this.namespaceAlias[node.namespaceURI]: this.defaultPrefix]; |
|
if(group) { |
|
var local = node.localName || node.nodeName.split(":").pop(); |
|
var reader = group[local] || group["*"]; |
|
if(reader) { |
|
reader.apply(this, [node, obj]); |
|
} |
|
} |
|
return obj; |
|
}, |
|
|
|
/** |
|
* Method: readChildNodes |
|
* Shorthand for applying the named readers to all children of a node. |
|
* For each child of type 1 (element), <readSelf> is called. |
|
* |
|
* Parameters: |
|
* node - {DOMElement} The node to be read (required). |
|
* obj - {Object} The object to be modified (optional). |
|
* |
|
* Returns: |
|
* {Object} The input object, modified. |
|
*/ |
|
readChildNodes: function(node, obj) { |
|
if(!obj) { |
|
obj = {}; |
|
} |
|
var children = node.childNodes; |
|
var child; |
|
for(var i=0, len=children.length; i<len; ++i) { |
|
child = children[i]; |
|
if(child.nodeType == 1) { |
|
this.readNode(child, obj); |
|
} |
|
} |
|
return obj; |
|
}, |
|
|
|
/** |
|
* Method: writeNode |
|
* Shorthand for applying one of the named writers and appending the |
|
* results to a node. If a qualified name is not provided for the |
|
* second argument (and a local name is used instead), the namespace |
|
* of the parent node will be assumed. |
|
* |
|
* Parameters: |
|
* name - {String} The name of a node to generate. If a qualified name |
|
* (e.g. "pre:Name") is used, the namespace prefix is assumed to be |
|
* in the <writers> group. If a local name is used (e.g. "Name") then |
|
* the namespace of the parent is assumed. If a local name is used |
|
* and no parent is supplied, then the default namespace is assumed. |
|
* obj - {Object} Structure containing data for the writer. |
|
* parent - {DOMElement} Result will be appended to this node. If no parent |
|
* is supplied, the node will not be appended to anything. |
|
* |
|
* Returns: |
|
* {DOMElement} The child node. |
|
*/ |
|
writeNode: function(name, obj, parent) { |
|
var prefix, local; |
|
var split = name.indexOf(":"); |
|
if(split > 0) { |
|
prefix = name.substring(0, split); |
|
local = name.substring(split + 1); |
|
} else { |
|
if(parent) { |
|
prefix = this.namespaceAlias[parent.namespaceURI]; |
|
} else { |
|
prefix = this.defaultPrefix; |
|
} |
|
local = name; |
|
} |
|
var child = this.writers[prefix][local].apply(this, [obj]); |
|
if(parent) { |
|
parent.appendChild(child); |
|
} |
|
return child; |
|
}, |
|
|
|
/** |
|
* APIMethod: getChildEl |
|
* Get the first child element. Optionally only return the first child |
|
* if it matches the given name and namespace URI. |
|
* |
|
* Parameters: |
|
* node - {DOMElement} The parent node. |
|
* name - {String} Optional node name (local) to search for. |
|
* uri - {String} Optional namespace URI to search for. |
|
* |
|
* Returns: |
|
* {DOMElement} The first child. Returns null if no element is found, if |
|
* something significant besides an element is found, or if the element |
|
* found does not match the optional name and uri. |
|
*/ |
|
getChildEl: function(node, name, uri) { |
|
return node && this.getThisOrNextEl(node.firstChild, name, uri); |
|
}, |
|
|
|
/** |
|
* APIMethod: getNextEl |
|
* Get the next sibling element. Optionally get the first sibling only |
|
* if it matches the given local name and namespace URI. |
|
* |
|
* Parameters: |
|
* node - {DOMElement} The node. |
|
* name - {String} Optional local name of the sibling to search for. |
|
* uri - {String} Optional namespace URI of the sibling to search for. |
|
* |
|
* Returns: |
|
* {DOMElement} The next sibling element. Returns null if no element is |
|
* found, something significant besides an element is found, or the |
|
* found element does not match the optional name and uri. |
|
*/ |
|
getNextEl: function(node, name, uri) { |
|
return node && this.getThisOrNextEl(node.nextSibling, name, uri); |
|
}, |
|
|
|
/** |
|
* Method: getThisOrNextEl |
|
* Return this node or the next element node. Optionally get the first |
|
* sibling with the given local name or namespace URI. |
|
* |
|
* Parameters: |
|
* node - {DOMElement} The node. |
|
* name - {String} Optional local name of the sibling to search for. |
|
* uri - {String} Optional namespace URI of the sibling to search for. |
|
* |
|
* Returns: |
|
* {DOMElement} The next sibling element. Returns null if no element is |
|
* found, something significant besides an element is found, or the |
|
* found element does not match the query. |
|
*/ |
|
getThisOrNextEl: function(node, name, uri) { |
|
outer: for(var sibling=node; sibling; sibling=sibling.nextSibling) { |
|
switch(sibling.nodeType) { |
|
case 1: // Element |
|
if((!name || name === (sibling.localName || sibling.nodeName.split(":").pop())) && |
|
(!uri || uri === sibling.namespaceURI)) { |
|
// matches |
|
break outer; |
|
} |
|
sibling = null; |
|
break outer; |
|
case 3: // Text |
|
if(/^\s*$/.test(sibling.nodeValue)) { |
|
break; |
|
} |
|
case 4: // CDATA |
|
case 6: // ENTITY_NODE |
|
case 12: // NOTATION_NODE |
|
case 10: // DOCUMENT_TYPE_NODE |
|
case 11: // DOCUMENT_FRAGMENT_NODE |
|
sibling = null; |
|
break outer; |
|
} // ignore comments and processing instructions |
|
} |
|
return sibling || null; |
|
}, |
|
|
|
/** |
|
* APIMethod: lookupNamespaceURI |
|
* Takes a prefix and returns the namespace URI associated with it on the given |
|
* node if found (and null if not). Supplying null for the prefix will |
|
* return the default namespace. |
|
* |
|
* For browsers that support it, this calls the native lookupNamesapceURI |
|
* function. In other browsers, this is an implementation of |
|
* http://www.w3.org/TR/DOM-Level-3-Core/core.html#Node3-lookupNamespaceURI. |
|
* |
|
* For browsers that don't support the attribute.ownerElement property, this |
|
* method cannot be called on attribute nodes. |
|
* |
|
* Parameters: |
|
* node - {DOMElement} The node from which to start looking. |
|
* prefix - {String} The prefix to lookup or null to lookup the default namespace. |
|
* |
|
* Returns: |
|
* {String} The namespace URI for the given prefix. Returns null if the prefix |
|
* cannot be found or the node is the wrong type. |
|
*/ |
|
lookupNamespaceURI: function(node, prefix) { |
|
var uri = null; |
|
if(node) { |
|
if(node.lookupNamespaceURI) { |
|
uri = node.lookupNamespaceURI(prefix); |
|
} else { |
|
outer: switch(node.nodeType) { |
|
case 1: // ELEMENT_NODE |
|
if(node.namespaceURI !== null && node.prefix === prefix) { |
|
uri = node.namespaceURI; |
|
break outer; |
|
} |
|
var len = node.attributes.length; |
|
if(len) { |
|
var attr; |
|
for(var i=0; i<len; ++i) { |
|
attr = node.attributes[i]; |
|
if(attr.prefix === "xmlns" && attr.name === "xmlns:" + prefix) { |
|
uri = attr.value || null; |
|
break outer; |
|
} else if(attr.name === "xmlns" && prefix === null) { |
|
uri = attr.value || null; |
|
break outer; |
|
} |
|
} |
|
} |
|
uri = this.lookupNamespaceURI(node.parentNode, prefix); |
|
break outer; |
|
case 2: // ATTRIBUTE_NODE |
|
uri = this.lookupNamespaceURI(node.ownerElement, prefix); |
|
break outer; |
|
case 9: // DOCUMENT_NODE |
|
uri = this.lookupNamespaceURI(node.documentElement, prefix); |
|
break outer; |
|
case 6: // ENTITY_NODE |
|
case 12: // NOTATION_NODE |
|
case 10: // DOCUMENT_TYPE_NODE |
|
case 11: // DOCUMENT_FRAGMENT_NODE |
|
break outer; |
|
default: |
|
// TEXT_NODE (3), CDATA_SECTION_NODE (4), ENTITY_REFERENCE_NODE (5), |
|
// PROCESSING_INSTRUCTION_NODE (7), COMMENT_NODE (8) |
|
uri = this.lookupNamespaceURI(node.parentNode, prefix); |
|
break outer; |
|
} |
|
} |
|
} |
|
return uri; |
|
}, |
|
|
|
CLASS_NAME: "OpenLayers.Format.XML" |
|
|
|
}); |
|
|
|
OpenLayers.Format.XML.CONTENT_TYPE = {EMPTY: 0, SIMPLE: 1, COMPLEX: 2, MIXED: 3}; |
|
|
|
/** |
|
* APIFunction: OpenLayers.Format.XML.lookupNamespaceURI |
|
* Takes a prefix and returns the namespace URI associated with it on the given |
|
* node if found (and null if not). Supplying null for the prefix will |
|
* return the default namespace. |
|
* |
|
* For browsers that support it, this calls the native lookupNamesapceURI |
|
* function. In other browsers, this is an implementation of |
|
* http://www.w3.org/TR/DOM-Level-3-Core/core.html#Node3-lookupNamespaceURI. |
|
* |
|
* For browsers that don't support the attribute.ownerElement property, this |
|
* method cannot be called on attribute nodes. |
|
* |
|
* Parameters: |
|
* node - {DOMElement} The node from which to start looking. |
|
* prefix - {String} The prefix to lookup or null to lookup the default namespace. |
|
* |
|
* Returns: |
|
* {String} The namespace URI for the given prefix. Returns null if the prefix |
|
* cannot be found or the node is the wrong type. |
|
*/ |
|
OpenLayers.Format.XML.lookupNamespaceURI = OpenLayers.Function.bind( |
|
OpenLayers.Format.XML.prototype.lookupNamespaceURI, |
|
OpenLayers.Format.XML.prototype |
|
); |
|
|