JavaScript Tutorial/XML/DOM

Материал из Web эксперт
Перейти к: навигация, поиск

Basic XML DOM Usage with zXml Library

   <source lang="javascript">

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <html> <head> <title>Basic XML DOM Usage</title> <script type="text/javascript"> /*------------------------------------------------------------------------------

* JavaScript zXml Library
* Version 1.0.2
* by Nicholas C. Zakas, http://www.nczonline.net/
* Copyright (c) 2004-2006 Nicholas C. Zakas. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
*------------------------------------------------------------------------------
*/  

var zXml /*:Object*/ = {

   useActiveX: (typeof ActiveXObject != "undefined"),
   useDom: document.implementation && document.implementation.createDocument,
   useXmlHttp: (typeof XMLHttpRequest != "undefined")

}; zXml.ARR_XMLHTTP_VERS /*:Array*/ = ["MSXML2.XmlHttp.6.0","MSXML2.XmlHttp.3.0"]; zXml.ARR_DOM_VERS /*:Array*/ = ["MSXML2.DOMDocument.6.0","MSXML2.DOMDocument.3.0"];

/**

* Static class for handling XMLHttp creation.
* @class
*/                     

function zXmlHttp() { } /**

* Creates an XMLHttp object.
* @return An XMLHttp object.
*/

zXmlHttp.createRequest = function ()/*:XMLHttp*/ {

   //if it natively supports XMLHttpRequest object
   if (zXml.useXmlHttp) {
       return new XMLHttpRequest();
   } else if (zXml.useActiveX) { //IE < 7.0 = use ActiveX
 
       if (!zXml.XMLHTTP_VER) {
           for (var i=0; i < zXml.ARR_XMLHTTP_VERS.length; i++) {
               try {
                   new ActiveXObject(zXml.ARR_XMLHTTP_VERS[i]);
                   zXml.XMLHTTP_VER = zXml.ARR_XMLHTTP_VERS[i];
                   break;
               } catch (oError) {                
               }
           }
       }
       
       if (zXml.XMLHTTP_VER) {
           return new ActiveXObject(zXml.XMLHTTP_VER);
       } else {
           throw new Error("Could not create XML HTTP Request.");
       }
   } else {
       throw new Error("Your browser doesn"t support an XML HTTP Request.");
   }

}; /**

* Indicates if XMLHttp is available.
* @return True if XMLHttp is available, false if not.
*/

zXmlHttp.isSupported = function ()/*:Boolean*/ {

   return zXml.useXmlHttp || zXml.useActiveX;

};

/**

* Static class for handling XML DOM creation.
* @class
*/

function zXmlDom() { } /**

* Creates an XML DOM document.
* @return An XML DOM document.
*/

zXmlDom.createDocument = function () /*:XMLDocument*/{

   if (zXml.useDom) {
       var oXmlDom = document.implementation.createDocument("","",null);
       oXmlDom.parseError = {
           valueOf: function () { return this.errorCode; },
           toString: function () { return this.errorCode.toString() }
       };
       
       oXmlDom.__initError__();
               
       oXmlDom.addEventListener("load", function () {
           this.__checkForErrors__();
           this.__changeReadyState__(4);
       }, false);
       return oXmlDom;        
       
   } else if (zXml.useActiveX) {
       if (!zXml.DOM_VER) {
           for (var i=0; i < zXml.ARR_DOM_VERS.length; i++) {
               try {
                   new ActiveXObject(zXml.ARR_DOM_VERS[i]);
                   zXml.DOM_VER = zXml.ARR_DOM_VERS[i];
                   break;
               } catch (oError) {                
               }
           }
       }
       
       if (zXml.DOM_VER) {
           return new ActiveXObject(zXml.DOM_VER);
       } else {
           throw new Error("Could not create XML DOM document.");
       }
   } else {
       throw new Error("Your browser doesn"t support an XML DOM document.");
   }

}; /**

* Indicates if an XML DOM is available.
* @return True if XML DOM is available, false if not.
*/

zXmlDom.isSupported = function ()/*:Boolean*/ {

   return zXml.useDom || zXml.useActiveX;

}; //Code to make Mozilla DOM documents act more like MS DOM documents. var oMozDocument = null; if (typeof XMLDocument != "undefined") {

   oMozDocument = XMLDocument;

} else if (typeof Document != "undefined") {

   oMozDocument = Document;

} if (oMozDocument && !window.opera) {

   oMozDocument.prototype.readyState = 0;
   oMozDocument.prototype.onreadystatechange = null;
   oMozDocument.prototype.__changeReadyState__ = function (iReadyState) {
       this.readyState = iReadyState;
       if (typeof this.onreadystatechange == "function") {
           this.onreadystatechange();
       }
   };
   oMozDocument.prototype.__initError__ = function () {
       this.parseError.errorCode = 0;
       this.parseError.filepos = -1;
       this.parseError.line = -1;
       this.parseError.linepos = -1;
       this.parseError.reason = null;
       this.parseError.srcText = null;
       this.parseError.url = null;
   };
   
   oMozDocument.prototype.__checkForErrors__ = function () {
       if (this.documentElement.tagName == "parsererror") {
           var reError = />([\s\S]*?)Location:([\s\S]*?)Line Number (\d+), Column (\d+):<sourcetext>([\s\S]*?)(?:\-*\^)/;
           reError.test(this.xml);
           
           this.parseError.errorCode = -999999;
           this.parseError.reason = RegExp.$1;
           this.parseError.url = RegExp.$2;
           this.parseError.line = parseInt(RegExp.$3);
           this.parseError.linepos = parseInt(RegExp.$4);
           this.parseError.srcText = RegExp.$5;
       }
   };
           
   oMozDocument.prototype.loadXML = function (sXml) {
   
       this.__initError__();
   
       this.__changeReadyState__(1);
   
       var oParser = new DOMParser();
       var oXmlDom = oParser.parseFromString(sXml, "text/xml");

       while (this.firstChild) {
           this.removeChild(this.firstChild);
       }
       for (var i=0; i < oXmlDom.childNodes.length; i++) {
           var oNewNode = this.importNode(oXmlDom.childNodes[i], true);
           this.appendChild(oNewNode);
       }
       
       this.__checkForErrors__();
       
       this.__changeReadyState__(4);
   };
   
   oMozDocument.prototype.__load__ = oMozDocument.prototype.load;
   oMozDocument.prototype.load = function (sURL) {
       this.__initError__();
       this.__changeReadyState__(1);
       this.__load__(sURL);
   };
   
   Node.prototype.__defineGetter__("xml", function () {
       var oSerializer = new XMLSerializer();
       return oSerializer.serializeToString(this, "text/xml");
   });
   Node.prototype.__defineGetter__("text", function () {
       var sText = "";
       for (var i = 0; i < this.childNodes.length; i++) {
           if (this.childNodes[i].hasChildNodes()) {
               sText += this.childNodes[i].text;
           } else {
               sText += this.childNodes[i].nodeValue;
           }
       }
       return sText;
   });

} /**

* Static class for handling XSLT transformations.
* @class
*/

function zXslt() { } /**

* Transforms an XML DOM to text using an XSLT DOM.
* @param oXml The XML DOM to transform.
* @param oXslt The XSLT DOM to use for the transformation.
* @return The transformed version of the string.
*/

zXslt.transformToText = function (oXml /*:XMLDocument*/, oXslt /*:XMLDocument*/)/*:String*/ {

   if (typeof XSLTProcessor != "undefined") {
       var oProcessor = new XSLTProcessor();
       oProcessor.importStylesheet(oXslt);
   
       var oResultDom = oProcessor.transformToDocument(oXml);
       var sResult = oResultDom.xml;
   
       if (sResult.indexOf("<transformiix:result") > -1) {
           sResult = sResult.substring(sResult.indexOf(">") + 1, 
                                       sResult.lastIndexOf("<"));
       }
   
       return sResult;     
   } else if (zXml.useActiveX) {
       return oXml.transformNode(oXslt);
   } else {
       throw new Error("No XSLT engine found.");
   }

}; /**

* Static class for handling XPath evaluation.
* @class
*/

function zXPath() { } /**

* Selects the first node matching a given XPath expression.
* @param oRefNode The node from which to evaluate the expression.
* @param sXPath The XPath expression.
* @param oXmlNs An object containing the namespaces used in the expression. Optional.
* @return An XML node matching the expression or null if no matches found.
*/

zXPath.selectNodes = function (oRefNode /*:Node*/, sXPath /*:String*/, oXmlNs /*:Object*/) {

   if (typeof XPathEvaluator != "undefined") {
   
       oXmlNs = oXmlNs || {};
       
       var nsResolver = function (sPrefix) {
                    return oXmlNs[sPrefix];
       };
         
       var oEvaluator = new XPathEvaluator();
       var oResult = oEvaluator.evaluate(sXPath, oRefNode, nsResolver, 
                                         XPathResult.ORDERED_NODE_ITERATOR_TYPE, 
                                         null);
       var aNodes = new Array;
       
       if (oResult != null) {
           var oElement = oResult.iterateNext();
           while(oElement) {
               aNodes.push(oElement);
               oElement = oResult.iterateNext();
           }
       }
       
       return aNodes;
       
   } else if (zXml.useActiveX) {
             if (oXmlNs) {
           var sXmlNs = "";
           for (var sProp in oXmlNs) {
               sXmlNs += "xmlns:" + sProp + "=\"" + oXmlNs[sProp] + "\" ";
           }
                    oRefNode.ownerDocument.setProperty("SelectionNamespaces", sXmlNs);
             }            
       return oRefNode.selectNodes(sXPath);
   } else {
       throw new Error("No XPath engine found.");
   }

}; /**

* Selects the first node matching a given XPath expression.
* @param oRefNode The node from which to evaluate the expression.
* @param sXPath The XPath expression.
* @param oXmlNs An object containing the namespaces used in the expression.
* @return An XML node matching the expression or null if no matches found.
*/

zXPath.selectSingleNode = function (oRefNode /*:Node*/, sXPath /*:String*/, oXmlNs /*:Object*/) {

   if (typeof XPathEvaluator != "undefined") {            
    
       oXmlNs = oXmlNs || {};
       
       var nsResolver = function (sPrefix) {
                    return oXmlNs[sPrefix];
       };
   
       var oEvaluator = new XPathEvaluator();
       var oResult = oEvaluator.evaluate(sXPath, oRefNode, nsResolver,
                                         XPathResult.FIRST_ORDERED_NODE_TYPE, null);
   
       if (oResult != null) {
           return oResult.singleNodeValue;
       } else {
           return null;
       }              
   
   } else if (zXml.useActiveX) {
             if (oXmlNs) {
           var sXmlNs = "";
           for (var sProp in oXmlNs) {
               sXmlNs += "xmlns:" + sProp + "=\"" + oXmlNs[sProp] + "\" ";
           }
                    oRefNode.ownerDocument.setProperty("SelectionNamespaces", sXmlNs);
             }    
       return oRefNode.selectSingleNode(sXPath);
   } else {
       throw new Error("No XPath engine found.")
   }

}; /**

* General purpose XML serializer.
* @class
*/

function zXMLSerializer() { } /**

* Serializes the given XML node into an XML string.
* @param oNode The XML node to serialize.
* @return An XML string.
*/

zXMLSerializer.prototype.serializeToString = function (oNode /*:Node*/)/*:String*/ {

   var sXml = "";
   
   switch (oNode.nodeType) {
       case 1: //element
           sXml = "<" + oNode.tagName;
           
           for (var i=0; i < oNode.attributes.length; i++) {
               sXml += " " + oNode.attributes[i].name + "=\"" + oNode.attributes[i].value + "\"";
           }
           
           sXml += ">";
           
           for (var i=0; i < oNode.childNodes.length; i++){
               sXml += this.serializeToString(oNode.childNodes[i]);
           }
           
           sXml += "</" + oNode.tagName + ">";
           break;
           
       case 3: //text node
           sXml = oNode.nodeValue;
           break;
       case 4: //cdata
           sXml = "<![CDATA[" + oNode.nodeValue + "";
           break;
       case 7: //processing instruction
           sXml = "<?" + oNode.nodevalue + "?>";
           break;
       case 8: //comment
           sXml = "";
           break;
       case 9: //document
           for (var i=0; i < oNode.childNodes.length; i++){
               sXml += this.serializeToString(oNode.childNodes[i]);
           }
           break;
           
   }  
   
   return sXml;

}; </script> </head> <body> <script>

   //create a DOM document
         var oXml = zXmlDom.createDocument();
         
         //fill it with some XML
         oXml.loadXML("<root><child index=\"1\"/><child index=\"2\"/><child index=\"1\"/><child index=\"3\"/></root>");
         
         //look around
         alert("Root is: " + oXml.documentElement.tagName);
      alert("First child is: " + oXml.documentElement.firstChild.tagName);
   

</script> </body> </html></source>