/***************************************************************************** * * Sarissa XML library version 0.9.6 * Copyright (c) 2003 Manos Batsis, * mailto: mbatsis at users full stop sourceforge full stop net * This software is distributed under the Kupu License. See * LICENSE.txt for license text. See the Sarissa homepage at * http://sarissa.sourceforge.net for more information. * ***************************************************************************** * ==================================================================== * About * ==================================================================== * Sarissa cross browser XML library - IE XPath Emulation * @version 0.9.6 * @author: Manos Batsis, mailto: mbatsis at users full stop sourceforge full stop net * * This script emulates Internet Explorer's selectNodes and selectSingleNode * for Mozilla. Associating namespace prefixes with URIs for your XPath queries * is easy with IE's setProperty. * USers may also map a namespace prefix to a default (unprefixed) namespace in the * source document with Sarissa.setXpathNamespaces * */ if(_SARISSA_HAS_DOM_FEATURE && document.implementation.hasFeature("XPath", "3.0")){ /** *

SarissaNodeList behaves as a NodeList but is only used as a result to selectNodes, * so it also has some properties IEs proprietery object features.

* @private * @constructor * @argument i the (initial) list size */ function SarissaNodeList(i){ this.length = i; }; /**

Set an Array as the prototype object

*/ SarissaNodeList.prototype = new Array(0); /**

Inherit the Array constructor

*/ SarissaNodeList.prototype.constructor = Array; /** *

Returns the node at the specified index or null if the given index * is greater than the list size or less than zero

*

Note that in ECMAScript you can also use the square-bracket * array notation instead of calling item * @argument i the index of the member to return * @returns the member corresponding to the given index */ SarissaNodeList.prototype.item = function(i) { return (i < 0 || i >= this.length)?null:this[i]; }; /** *

Emulate IE's expr property * (Here the SarissaNodeList object is given as the result of selectNodes).

* @returns the XPath expression passed to selectNodes that resulted in * this SarissaNodeList */ SarissaNodeList.prototype.expr = ""; /** dummy, used to accept IE's stuff without throwing errors */ XMLDocument.prototype.setProperty = function(x,y){}; /** *

Programmatically control namespace URI/prefix mappings for XPath * queries.

*

This method comes especially handy when used to apply XPath queries * on XML documents with a default namespace, as there is no other way * of mapping that to a prefix.

*

Using no namespace prefix in DOM Level 3 XPath queries, implies you * are looking for elements in the null namespace. If you need to look * for nodes in the default namespace, you need to map a prefix to it * first like:

*
Sarissa.setXpathNamespaces(oDoc, "xmlns:myprefix=&aposhttp://mynsURI&apos");
*

Note 1 : Use this method only if the source document features * a default namespace (without a prefix), otherwise just use IE's setProperty * (moz will rezolve non-default namespaces by itself). You will need to map that * namespace to a prefix for queries to work.

*

Note 2 : This method calls IE's setProperty method to set the * appropriate namespace-prefix mappings, so you dont have to do that.

* @param oDoc The target XMLDocument to set the namespace mappings for. * @param sNsSet A whilespace-seperated list of namespace declarations as * those would appear in an XML document. E.g.: * "xmlns:xhtml='http://www.w3.org/1999/xhtml' * xmlns:'http://www.w3.org/1999/XSL/Transform'" * @throws An error if the format of the given namespace declarations is bad. */ Sarissa.setXpathNamespaces = function(oDoc, sNsSet) { //oDoc._sarissa_setXpathNamespaces(sNsSet); oDoc._sarissa_useCustomResolver = true; var namespaces = sNsSet.indexOf(" ")>-1?sNsSet.split(" "):new Array(sNsSet); oDoc._sarissa_xpathNamespaces = new Array(namespaces.length); for(var i=0;i < namespaces.length;i++){ var ns = namespaces[i]; var colonPos = ns.indexOf(":"); var assignPos = ns.indexOf("="); if(colonPos == 5 && assignPos > colonPos+2){ var prefix = ns.substring(colonPos+1, assignPos); var uri = ns.substring(assignPos+2, ns.length-1); oDoc._sarissa_xpathNamespaces[prefix] = uri; }else{ throw "Bad format on namespace declaration(s) given"; }; }; }; /** * @private Flag to control whether a custom namespace resolver should * be used, set to true by Sarissa.setXpathNamespaces */ XMLDocument.prototype._sarissa_useCustomResolver = false; /** @private */ XMLDocument.prototype._sarissa_xpathNamespaces = new Array(); /** *

Extends the XMLDocument to emulate IE's selectNodes.

* @argument sExpr the XPath expression to use * @argument contextNode this is for internal use only by the same * method when called on Elements * @returns the result of the XPath search as a SarissaNodeList * @throws An error if no namespace URI is found for the given prefix. */ XMLDocument.prototype.selectNodes = function(sExpr, contextNode){ var nsDoc = this; var nsresolver = this._sarissa_useCustomResolver ? function(prefix){ var s = nsDoc._sarissa_xpathNamespaces[prefix]; if(s)return s; else throw "No namespace URI found for prefix: '" + prefix+"'"; } : this.createNSResolver(this.documentElement); var oResult = this.evaluate(sExpr, (contextNode?contextNode:this), nsresolver, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null); var nodeList = new SarissaNodeList(oResult.snapshotLength); nodeList.expr = sExpr; for(var i=0;iExtends the Element to emulate IE's selectNodes

* @argument sExpr the XPath expression to use * @returns the result of the XPath search as an (Sarissa)NodeList * @throws An * error if invoked on an HTML Element as this is only be * available to XML Elements. */ Element.prototype.selectNodes = function(sExpr){ var doc = this.ownerDocument; if(doc.selectNodes) return doc.selectNodes(sExpr, this); else throw "Method selectNodes is only supported by XML Elements"; }; /** *

Extends the XMLDocument to emulate IE's selectSingleNodes.

* @argument sExpr the XPath expression to use * @argument contextNode this is for internal use only by the same * method when called on Elements * @returns the result of the XPath search as an (Sarissa)NodeList */ XMLDocument.prototype.selectSingleNode = function(sExpr, contextNode){ var ctx = contextNode?contextNode:null; sExpr = "("+sExpr+")[1]"; var nodeList = this.selectNodes(sExpr, ctx); if(nodeList.length > 0) return nodeList.item(0); else return null; }; /** *

Extends the Element to emulate IE's selectNodes.

* @argument sExpr the XPath expression to use * @returns the result of the XPath search as an (Sarissa)NodeList * @throws An error if invoked on an HTML Element as this is only be * available to XML Elements. */ Element.prototype.selectSingleNode = function(sExpr){ var doc = this.ownerDocument; if(doc.selectSingleNode) return doc.selectSingleNode(sExpr, this); else throw "Method selectNodes is only supported by XML Elements"; }; Sarissa.IS_ENABLED_SELECT_NODES = true; };