Making it so format.getChildValue concatenates all simple content (except for GeoRSS format). Use getChildValue instead of concatChildValues. Adding a number of other format methods for those who do manual dom traversal. Original patch from dparker. r=me (see #1846)

git-svn-id: http://svn.openlayers.org/trunk/openlayers@9180 dc9f47b5-9b13-0410-9fdd-eb0c1a62fdaf
This commit is contained in:
Tim Schaub
2009-04-03 19:17:49 +00:00
parent e1b1c814de
commit d1898d1a7d
6 changed files with 407 additions and 11 deletions

View File

@@ -349,7 +349,7 @@ OpenLayers.Format.XML = OpenLayers.Class(OpenLayers.Format, {
/**
* APIMethod: getChildValue
* Get the value of the first child node if it exists, or return an
* 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.
*
@@ -364,9 +364,12 @@ OpenLayers.Format.XML = OpenLayers.Class(OpenLayers.Format, {
getChildValue: function(node, def) {
var value = def || "";
if(node) {
var child = node.firstChild;
if(child) {
value = child.nodeValue || value;
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;
@@ -374,6 +377,8 @@ OpenLayers.Format.XML = OpenLayers.Class(OpenLayers.Format, {
/**
* 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
@@ -403,6 +408,70 @@ OpenLayers.Format.XML = OpenLayers.Class(OpenLayers.Format, {
}
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
@@ -627,6 +696,185 @@ OpenLayers.Format.XML = OpenLayers.Class(OpenLayers.Format, {
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
);