<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>西红柿爱番茄 &#187; XML</title>
	<atom:link href="http://www.ilovejs.net/archives/tag/xml/feed" rel="self" type="application/rss+xml" />
	<link>http://www.ilovejs.net</link>
	<description>到了创造为主的阶段，不忘继续学习</description>
	<lastBuildDate>Thu, 15 Dec 2011 06:18:39 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3</generator>
		<item>
		<title>封装复杂的XML DOM操作</title>
		<link>http://www.ilovejs.net/archives/37</link>
		<comments>http://www.ilovejs.net/archives/37#comments</comments>
		<pubDate>Sat, 19 Dec 2009 15:51:10 +0000</pubDate>
		<dc:creator>Supersha</dc:creator>
				<category><![CDATA[Javascript]]></category>
		<category><![CDATA[XML]]></category>

		<guid isPermaLink="false">http://www.ilovejs.net/?p=37</guid>
		<description><![CDATA[在这里我要介绍一个我早些时间编写的一个封装XML DOM操作的库 CXML。写这个库的原因都是基于对XML DOM操作的繁杂性和重复性，况且不用说它的效率底下了，这是我们都感同身受的。CXML可以操作导入的xml文件以及xml字符串，CXML里提供了四个接口方法：load,toXMLString,getXMLObject,selectNodes。需要指出的一点是，load和selectNodes方法是最强大的部分。当然了，CXML同时还可以跟使用Ajax通过responseXML返回的XML DOM对象结合使用。 load:提供了一个参数，该参数可以一个xml文件的URL，也可以是一段符合xml语法的xml字符串。比如：cxml.load(“supersha24“)，或者cxml.load(“http://www.ilovejs.net/xml/test.xml”); toXMLString:该方法带有一个可选择的node节点，返回该节点内的xml字符串，默认是XML DOM实力对象。 getXMLObject：返回XML DOM实力对象。 selectNodes：该方法的参数是一个css形式的selectors，从XML DOM对象中查询节点集合。支持的selectors在下面会有说明。 同时需要说明的是：selectNodes方法内是通过XPath来查询XML DOM实例对象的，不过它扩展了一些css形式的selectors，其他的XPath形式的查询字符串都是支持的，因为它给予XPath的查询。CXML在编写的过程中遇到的唯一的问题就是Google Chrome 和 Safari载入xml文件的时候无法生成XML DOM对象的兼容性问题，这个问题琢磨了有些时间。最后不得不使用这种的方式，对Google Chrome和Safari使用XMLHttpRequest的方式来加载，通过responseXML的形式来返回XML DOM对象。不过Google &#8230; <a href="http://www.ilovejs.net/archives/37" class="more-link">了解更多</a>]]></description>
			<content:encoded><![CDATA[<p>
在这里我要介绍一个我早些时间编写的一个封装XML DOM操作的库 <a href="http://www.ilovejs.net/archives/37">CXML</a>。写这个库的原因都是基于对XML DOM操作的繁杂性和重复性，况且不用说它的效率底下了，这是我们都感同身受的。CXML可以操作导入的xml文件以及xml字符串，CXML里提供了四个接口方法：load,toXMLString,getXMLObject,selectNodes。需要指出的一点是，load和selectNodes方法是最强大的部分。当然了，CXML同时还可以跟使用Ajax通过responseXML返回的XML DOM对象结合使用。
</p>
<ul>
<li>load:提供了一个参数，该参数可以一个xml文件的URL，也可以是一段符合xml语法的xml字符串。比如：cxml.load(“<item><name>supersha</name><age>24</age></item>“)，或者cxml.load(“http://www.ilovejs.net/xml/test.xml”);
</li>
<li>toXMLString:该方法带有一个可选择的node节点，返回该节点内的xml字符串，默认是XML DOM实力对象。</li>
<li>getXMLObject：返回XML DOM实力对象。</li>
<li>selectNodes：该方法的参数是一个css形式的selectors，从XML DOM对象中查询节点集合。支持的selectors在下面会有说明。</li>
</ul>
<p><span id="more-37"></span></p>
<p>
同时需要说明的是：selectNodes方法内是通过XPath来查询XML DOM实例对象的，不过它扩展了一些css形式的selectors，其他的XPath形式的查询字符串都是支持的，因为它给予XPath的查询。CXML在编写的过程中遇到的唯一的问题就是Google Chrome 和 Safari载入xml文件的时候无法生成XML DOM对象的兼容性问题，这个问题琢磨了有些时间。最后不得不使用这种的方式，对Google Chrome和Safari使用XMLHttpRequest的方式来加载，通过responseXML的形式来返回XML DOM对象。不过Google Chrome和Safari对加载xml字符串的形式是可以的。
</p>
<p>CXML目前支持的css形式的selectors有(顺便也附带上例子吧 <img src='http://www.ilovejs.net/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  )，不过这些selectors最终都会转化为XPath的方式来查询：<br />
[javascript]<br />
//下面是载入XML字符串的形式<br />
var cxml=new CXML();<br />
cxml.load(&quot;&lt;item id=&#8217;it&#8217;&gt;&lt;name&gt;supersha&lt;/name&gt;&lt;age&gt;24&lt;/age&gt;&lt;/item&gt;&quot;);<br />
cxml.selectNodes(&quot;item&quot;); //得到全部item元素的引用<br />
cxml.selectNodes(&quot;item:attr[@id]&quot;);<br />
cxml.selectNodes(&quot;item:first-child&quot;); //or cxml.selectNodes(&quot;item:first&quot;);<br />
cxml.selectNodes(&quot;item &gt; name&quot;);<br />
cxml.selectNodes(&quot;item:last-child&quot;); // or cxml.selectNodes(&quot;item:last&quot;);<br />
cxml.selectNodes(&quot;item:only-child&quot;);<br />
cxml.selectNodes(&quot;item:nth-child(1)&quot;);<br />
cxml.selectNodes(&quot;item:text&quot;);<br />
cxml.selectNodes(&quot;item,name&quot;);</p>
<p>//下面是载入XML文件的方式<br />
var cxml=new CXML();<br />
cxml.load(&quot;http://www.ilovejs.net/xml/test.xml&quot;,true,function(oXml){<br />
      oXml.selectNodes(&quot;item&quot;);<br />
      &#8230;&#8230;<br />
}</p>
<p>//下面是跟Ajax结合的方式<br />
var cxml=new CXML(request.responseXML);<br />
cxml.selectNodes(&quot;item:only-child&quot;);<br />
cxml.selectNodes(&quot;item:nth-child(1)&quot;);<br />
cxml.selectNodes(&quot;item:text&quot;);<br />
cxml.selectNodes(&quot;item,name&quot;);<br />
[/javascript]<br />
可怜的是IE对XPath支持的太少，Fuck IE！！！下面是展示CXML的源码：<br />
[javascript]<br />
(function(){<br />
    //使得Mozilla浏览器能兼容IE的使用方法而定义xml属性和loadXML方法<br />
    if (document.__defineGetter__) {<br />
        Node.prototype.__defineGetter__(&quot;xml&quot;, function(){<br />
            //Mozilla浏览器要获取xml代码，需要使用XMLSerializer对象<br />
            //XMLSerializer对象对象的唯一方法是serializeToString()，<br />
            //它接受一个oXmlDom节点和一个内容类型作为参数<br />
            var os = new XMLSerializer();<br />
            return os.serializeToString(this, &quot;text/xml&quot;);<br />
        });<br />
        Document.prototype.loadXML = function(sXML){<br />
            //Mozilla下要想载入XML类型的字符串，必须使用DOMParser对象<br />
            //parseFromString()是DOMParser对象的唯一方法，<br />
            //以药解析的xml字符串以及内容类型为参数，并返回一个XML DOM实例对象<br />
            var oParser = new DOMParser();<br />
            var oXml = oParser.parseFromString(sXML, &quot;text/xml&quot;);<br />
            //清除掉原本的XML DOM对象的内容<br />
            while (this.firstChild) {<br />
                this.removeChild(this.firstChild);<br />
            }<br />
            //使用XML DOM对象的importNode方法获取节点并添加到XML DOM对象中<br />
            for (var i = 0, l = oXml.childNodes.length; i &lt; l; i++) {<br />
                this.appendChild(this.importNode(oXml.childNodes[i], true));<br />
            }<br />
        }<br />
        //这个是位Mozilla浏览器扩展的selectNodes方法，目的是<br />
        //让它跟IE的selectNodes方法有相同的使用方式<br />
        //并且以一个XPath字符串作为参数<br />
        Element.prototype.selectNodes = function(sXPath){<br />
            //Mozilla浏览器中处理XPath相关的对象主要是：XPathEvaluator和XPathResult对象<br />
            //XPathEvaluator利用它的evaluate方法计算XPath，并返回结果集<br />
            //但是需要注意的是：返回的节点集合没有length属性，所以不得不利用<br />
            //iterateNext方法循环取得结果节点集合的值并添加到数组中<br />
            var oEvaluator = new XPathEvaluator();<br />
            var oResult = oEvaluator.evaluate(sXPath, this, null, XPathResult.ORDERED_NODE_ITERATOR_TYPE, null);<br />
            var aNodes = [];<br />
            if (oResult != null) {<br />
                var elem = oResult.iterateNext();<br />
                while (elem) {<br />
                    aNodes.push(elem);<br />
                    elem = oResult.iterateNext();<br />
                }<br />
            }<br />
            return aNodes;<br />
        }<br />
    }<br />
    //跨浏览器声明XML Document实例对象<br />
    var createXML = function(oXml){<br />
        if (oXml &amp;&amp; typeof oXml === &quot;object&quot;) {<br />
            return oXml;<br />
        }<br />
        var xml = false;<br />
        //Mozilla<br />
        if (document.implementation &amp;&amp; document.implementation.createDocument) {<br />
            xml = document.implementation.createDocument(&quot;&quot;, &quot;&quot;, null);<br />
            return xml;<br />
        } else if (window.ActiveXObject) { // IE<br />
            var args = [&quot;MSXML2.DOMDocument.5.0&quot;, &quot;MSXML2.DOMDocument.4.0&quot;, &quot;MSXML2.DOMDocument.3.0&quot;, &quot;MSXML2.DOMDocument&quot;, &quot;Microsoft.XmlDom&quot;];<br />
            for (var i = 0, l = args.length; i &lt; l; i++) {<br />
                try {<br />
                    xml = new ActiveXObject(args[i]);<br />
                    return xml;<br />
                }<br />
                catch (e) {<br />
                }<br />
            }<br />
        } else {<br />
            return false;<br />
        }<br />
    }<br />
    //判断是否是Chrome和Safari浏览器<br />
    var isChromeOrSafari = function(){<br />
        var userAgent = window.navigator.userAgent;<br />
        if (userAgent.indexOf(&quot;Chrome&quot;) !== -1 || userAgent.indexOf(&quot;Safari&quot;) !== -1) {<br />
            return true;<br />
        }<br />
        return false;<br />
    }<br />
    var CXML = function(oXML){<br />
        this.xml = createXML(oXML);<br />
    }<br />
    //sXML:可以是xml文件路径（相对或者绝对），xml格式的字符串<br />
    //async:是异步加载（true），还是同步（false）<br />
    //callback:加载xml文件完毕之后调用的回调函数，该函数的参数为当前的XML DOM对象<br />
    CXML.prototype.load = function(sXML, async, callback){<br />
        var that = this;<br />
        that.xml.async = async || true;<br />
        //以文件的形式载入<br />
        if (/.+\.xml/.test(sXML)) {<br />
            //利用XMLHttpRequest对象来处理Chrome和Safari浏览器无法载入xml文件的兼容处理方法<br />
            //不过Chrome、Safari浏览器对载入XML字符串是支持的<br />
            if (isChromeOrSafari()) {<br />
                var xhr = new XMLHttpRequest();<br />
                xhr.open(&quot;GET&quot;, sXML, async);<br />
                xhr.onreadystatechange = function(){<br />
                    if (xhr.readyState === 4 &amp;&amp; (xhr.status === 200 || xhr.status === 304)) {<br />
                        that.xml = xhr.responseXML;<br />
                        callback ? callback(that.xml) : null;<br />
                    }<br />
                }<br />
                xhr.send(null);<br />
            } else {<br />
                try {<br />
                    //Mozilla，在异步载入xml文件的时候，需要利用onload事件来判断文件是否载入完成<br />
                    that.xml.onload = function(){<br />
                        callback ? callback(that.xml) : null;<br />
                    }<br />
                }<br />
                catch (e) {<br />
                    // IE,在异步载入xml文件的时候，IE会有一个readyState的改变，<br />
                    //因此，会触发onreadystatechange事件<br />
                    that.xml.onreadystatechange = function(){<br />
                        if (that.xml.readyState === 4) {<br />
                            callback ? callback(that.xml) : null;<br />
                        }<br />
                    }<br />
                }<br />
                that.xml.load(sXML);<br />
            }<br />
        } else if (/&lt;[^&gt;]*/.test(sXML)) { //以XML字符串的形式载入<br />
            that.xml.loadXML(sXML);<br />
        }<br />
    }<br />
    //用于输出指定节点node开始的xml字符串<br />
    CXML.prototype.toXMLString = function(node){<br />
        node = node || this.xml;<br />
        return node.xml;<br />
    }<br />
    //返回XML DOM对象<br />
    CXML.prototype.getXMLObject = function(){<br />
        return this.xml;<br />
    }<br />
    //利用XPath在XML文档中进行查找符合XPath条件的节点集合<br />
    CXML.prototype.selectNodes = function(sXPath){<br />
        var regs = [/^(\w+)/, /\s?(,)\s?/g, /(:text)/g, /:attr\[@(\w+)\]/g, /(:first-child)|(:first)/g, /(:last-child)|(:last)/g, /(\s?&gt;\s?)/g, /:nth-child\((\d+)\)/g, /:only-child/g, /(?=\s)(\w+\[@\w+\])/g];<br />
        var xpath = [&quot;//$1&quot;, &quot;|//&quot;, &quot;/text()&quot;, &quot;/attribute::$1&quot;, &quot;/child::*[1]&quot;, &#8216;/child::*[last()]&#8216;, &quot;/&quot;, &quot;/child::*[$1]&quot;, &quot;/child::*&quot;, &quot;//$1&quot;];<br />
        for (var i = 0, l = regs.length; i &lt; l; i++) {<br />
            sXPath = sXPath.replace(regs[i], xpath[i]);<br />
        }<br />
        var nodes = this.xml.documentElement.selectNodes(sXPath);<br />
        return nodes.length === 1 ? nodes[0] : nodes;<br />
    }<br />
    window.CXML = CXML;<br />
})();<br />
[/javascript]</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ilovejs.net/archives/37/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

