📄 xmltools.js
字号:
/*
* Isomorphic SmartClient
* Version 6.5 (2008-04-30)
* Copyright(c) 1998-2007 Isomorphic Software, Inc. All rights reserved.
* "SmartClient" is a trademark of Isomorphic Software, Inc.
*
* licensing@smartclient.com
*
* http://smartclient.com/license
*/
//> @type XMLDocument// XMLDocument is the "parsed" or object form of XML, which allows XML to be navigated as// a tree of nodes with attributes, namespaces and other metadata, as opposed to being// manipulated as just a String.// <P> // XMLDocument is a native object supplied directly by the browser. The SmartClient-supported// interfaces for this object are methods that take an XMLDocument as an argument (such as// +link{XMLTools.selectNodes()}). If you want to retrieve XML data and display it in a// SmartClient component, read about +link{group:clientDataIntegration,XML Data Binding}. To// extract data as JavaScript Objects from XML, see +link{XMLTools.toJS()}. Direct// manipulation of XMLDocument is subject to cross-browser inconsistencies, bugs, memory leaks// and performance issues.//// @visibility xmlBinding//<//> @type XMLElement// An XMLElement represents one complete XML tag, including any subelements contained between// the start and end tags.// <P>// XMLElement is a native object supplied directly by the browser. The SmartClient-supported// interfaces for this object include methods that take an XMLElement as an argument (such as// +link{XMLTools.selectNodes()}). If you want to retrieve XML data and display it in a// SmartClient component, read about +link{group:clientDataIntegration,XML Data Binding}. To// extract data as JavaScript Objects from XML, see +link{XMLTools.toJS()}. Direct// manipulation of XMLElements objects is subject to cross-browser inconsistencies, bugs,// memory leaks and performance issues.//// @visibility xmlBinding//< isc.defineClass("XMLDoc").addMethods({ addPropertiesOnCreate:false, init : function (xmlDoc, namespaces) { this.nativeDoc = xmlDoc; this.namespaces = namespaces; // the most common property access this.documentElement = this.nativeDoc.documentElement; }, hasParseError : function () { if (isc.Browser.isIE) return this.nativeDoc.parseError != null; return this.nativeDoc.documentElement.tagName == "parsererror"; //FF }, addNamespaces : function (namespaces) { this.namespaces = this._combineNamespaces(namespaces); // HACK: in the Comm watcher, for experimenting with XPath selection against XML // replies, it's key that any namespaces added to the XMLDoc are available. if (this._responseID) { var xmlResponse = isc.xml.xmlResponses.find("ID", this._responseID); if (xmlResponse) xmlResponse.xmlNamespaces = this.namespaces; //this.logWarn("looked up response: " + this._responseID + // " and grabbed namespaces : " + this.echo(this.namespaces)); } }, _combineNamespaces : function (namespaces) { if (namespaces == null) return this.namespaces; if (this.namespaces == null) return namespaces; return isc.addProperties({}, this.namespaces, namespaces); }, // convenience methods selectNodes : function (xPath, namespaces, single) { return isc.xml.selectNodes(this.nativeDoc, xPath, this._combineNamespaces(namespaces), single); }, selectString : function (xPath, namespaces) { return isc.xml.selectString(this.nativeDoc, xPath, this._combineNamespaces(namespaces)); }, selectNumber : function (xPath, namespaces) { return isc.xml.selectNumber(this.nativeDoc, xPath, this._combineNamespaces(namespaces)); }, selectScalar : function (xPath, namespaces, asNumber) { return isc.xml.selectScalar(this.nativeDoc, xPath, this._combineNamespaces(namespaces), asNumber); }, selectScalarList : function (xPath, namespaces) { return isc.xml.selectScalarList(this.nativeDoc, xPath, this._combineNamespaces(namespaces)); }, // passthroughs (consider writePassthroughFunctions() if this expands) getElementById : function (id) { return this.nativeDoc.getElementById(id) }, getElementsByTagName : function (tagName) { return this.nativeDoc.getElementsByTagName(tagName) }});isc.XMLDoc.getPrototype().toString = function () { return "[XMLDoc <" + this.documentElement.tagName + ">]";};//> @class XMLTools// Utility methods for dealing with XML elements, XML Schema, WSDL files, XSLT, and other// XML-related functionality.//// @treeLocation Client Reference/Data Binding// @visibility external//<isc.defineClass("XMLTools").addClassProperties({ httpProxyURL: "[ISOMORPHIC]/HttpProxy"});isc.XMLTools.addClassMethods({// Retrieval and Parsing// ---------------------------------------------------------------------------------------//> @classMethod XMLTools.loadXML()// Load an XML document from the origin server or from a foreign server by relaying through the// origin server. An asynchronous callback provides both the XML document and raw text of the// response.// <P>// Relaying through the origin server requires that the ISC HttpProxyServlet be installed and// accessible.// // @param URL (URL) URL to load the schema from// @param callback (callback) callback to fire when the XML is loaded. Signature is// callback(xmlDoc, xmlText)// @param [requestProperties] (RPCRequest) additional properties to set on the RPCRequest// that will be issued//// @visibility external//<loadXML : function (url, callback, requestProperties) { this.getXMLResponse(isc.addProperties({ actionURL : url, httpMethod:"GET", callback:callback }, requestProperties));},// getXMLResponse: like rpc.sendProxied(), but parses the result as XML and gives an// XML-specific callback of (xmlDoc,xmlText)getXMLResponse : function (request) { // do an indirect callback request._xmlIndirectCallback = request.callback; request.callback = { target : this, methodName : "_getXMLResponseReply" }; // default to POST request.httpMethod = request.httpMethod || "POST"; this.logInfo("loading XML from: " + request.actionURL, "xmlComm"); isc.rpc.sendProxied(request);},xmlResponses : [],_nextResponseID : 0,_getXMLResponseReply : function (rpcResponse, data, rpcRequest) { var xmlText = rpcResponse.httpResponseText, xmlDoc = this.parseXML(xmlText); if (this.logIsInfoEnabled("xmlComm")) { this.logInfo("XML reply with text: " + (this.logIsDebugEnabled("xmlComm") ? xmlText : this.echoLeaf(xmlText)), "xmlComm"); } // retain last 5 responses in an Array for programmatic debugging var responses = this.xmlResponses; // NOTE: with the log window permanently open, you only need to enable xmlComm to catch // comm responses before page load var logViewer = isc.Log.logViewer; if (this.logIsDebugEnabled("xmlComm") || (isc.Page.isLoaded() && logViewer && logViewer.logWindowLoaded())) { var responseID = this._nextResponseID++; responses.add({ ID : responseID, text : xmlText }); // HACK: label the XMLDoc created from this xmlText with the id of the response - this // allows the XMLDoc to tack xml namespaces onto the response later xmlDoc._responseID = responseID; // keep a limited number of responses if (responses.length > 10) responses.shift(); // update log window if showing if (logViewer && logViewer.logWindowLoaded() && logViewer._logWindow != null) { logViewer._logWindow.updateCommWatcher(); } } else { responses.length = 0; } this.fireCallback(rpcRequest._xmlIndirectCallback, // NOTE: request/response probably only for internal callers "xmlDoc,xmlText,rpcResponse,rpcRequest", [xmlDoc,xmlText,rpcResponse,rpcRequest]);},// IE6 IE5.5 we used to use thisxmlDOMConstructors : ["MSXML2.DOMDocument", "MSXML.DOMDocument", "Microsoft.XMLDOM"],//> @classMethod XMLTools.parseXML()// Parse XML text into an +link{XMLDocument}. Parse errors, if any, are reported to the log.//// @param xmlText (String) XML text to be parsed// @return (XMLDocument) resulting XMLDocument// @visibility external//<mozAnchorBug : isc.Browser.isMoz && (isc.Browser.geckoVersion < 20080205) && window.location.href.indexOf("#") != -1,parseXML : function (xml, suppressErrors) { if (xml == null) return; // Moz will actually throw exceptions in this case xml = this.trimXMLStart(xml); var doc; if (!isc.Browser.isIE) { try { if ((this.mozAnchorBug || this.useAnchorWorkaround) && this.useAnchorWorkaround !== false) { var iframeHTML = "<IFRAME STYLE='position:absolute;visibility:hidden;top:-1000px'" +" ID='isc_parseXMLFrame'></IFRAME>"; if (!isc.Page.isLoaded()) { document.write(iframeHTML); } else { isc.Element.insertAdjacentHTML(document.getElementsByTagName("body")[0], "beforeEnd", iframeHTML) } var iframe = document.getElementById("isc_parseXMLFrame"); var iframeWindow = iframe.contentWindow; window.isc.xmlSource = xml; iframeWindow.location.href = "javascript:top.isc.parsedXML=" + "new top.isc.XMLTools.getXMLParser().parseFromString(top.isc.xmlSource, 'text/xml')"; doc = window.isc.parsedXML; isc.xmlSource = isc.parsedXML = null; // remove the iframe iframe.parentNode.removeChild(iframe); } else { doc = this.getXMLParser().parseFromString(xml, "text/xml"); } } catch (e) { if (!suppressErrors) this._logParseError(this.echo(e)); return null; } if (!suppressErrors && doc.documentElement.tagName == "parsererror") { this._logParseError(doc.documentElement.textContent); return null; } return isc.XMLDoc.create(doc); } doc = this.getXMLParser(); if (!doc) { this._warnIfNativeXMLUnavailable("XMLTools.parseXML()"); return; } doc.loadXML(xml); if (doc.parseError != 0) { var error = doc.parseError; if (!suppressErrors) { this._logParseError( "\rReason: " + error.reason + "Line number: " + error.line + ", character: " + error.linepos + "\rLine contents: " + error.srcText + (!isc.isA.emptyString(error.url) ? "\rSource URL: " + error.url : "")); } return null; } return isc.XMLDoc.create(doc);},// NOTE: don't obfuscate "trimXMLStart", used by dev consoletrimXMLStart : function (xml) { if (xml.indexOf("<?xml") != -1) { var match = xml.match(new RegExp("^\\s*<\\?.*\\?>")); if (match) { xml = xml.substring(match[0].length); //this.logWarn("match is: " + this.echoAll(match) + ", trimming by: " + match[0].length); } } if (isc.Browser.isIE && xml.indexOf("<!DOCTYPE") != -1) { var match = xml.match(new RegExp("^\\s*<!DOCTYPE .*>")); if (match) { xml = xml.substring(match[0].length); //this.logWarn("match is: " + this.echoAll(match) + ", trimming by: " + match[0].length); } } return xml;},_logParseError : function (errorText, xml) { this.logWarn("Error parsing XML: " + errorText + (this.logIsDebugEnabled("parseXML") ? "\rXML was:\r" + xml + "\rTrace:" + this.getStackTrace() : ""), "parseXML"); },getXMLParser : function () { // Moz/Firefox, Safari support a native DOMParser if (!isc.Browser.isIE) { if (!this._parser) this._parser = new DOMParser(); return this._parser; } var parser; if (this._xmlDOMConstructor) { parser = new ActiveXObject(this._xmlDOMConstructor); } else {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -