《 JavaScript高级程序设计》第15章知识
呵呵,全是从读书频道中抄过来的,所以直接跳15章了http://book.csdn.net/bookfiles/110/index.htm
15.1 浏览器中的XML DOM支持
仅有两个浏览器IE和Mozilla可以支持客户端的XML处理。
微软在JavaScript中引入了用于创建ActiveX对象的ActiveXObject类。ActiveXObject的构造函数只有一个参数——要进行实例化的ActiveX对象的字符串代号。例如,XML DOM对象的第一个版本称为Microsoft.XmlDom。所以,要创建这个对象的实例,使用以下代码:
执行这行代码后,oXmlDom对象就同其他DOM Document的对象行为完全一样了
开发人员首次使用这个XML处理方法时,经常会出现问题,因为用户常常未安装MSXML。绝大多数情况,开发人员必须直接从微软下载这个库。不过,IE 5.0修复了这个问题,它直接搭载了MSXML,这就确保了用IE 5.0或更高版本的用户一定可以使用这个功能。
1.DOM创建
对每个新版本的MSXML,都会创建出不同的XML DOM对象,而它们各自的名称也不相同。MSXML最新的版本是5.0,也就是说,存在以下XML DOM实现:
q Microsoft.XmlDom(最原始的);
q MSXML2.DOMDocument;
q MSXML2.DOMDocument.3.0;
q MSXML2.DOMDocument.4.0;
q MSXML2.DOMDocument.5.0。
为确保使用了正确的XML DOM版本,也为避免任何其他错误,我们可以创建一个函数来测试每个XML DOM字符串,出现错误即捕获:
2.载入XML
现在已有个可用的XML DOM对象,就可以载入一些XML了。微软的XML DOM有两种载入XML的方法:loadXML()和load()。
loadXML()方法可直接向XML DOM输入XML字符串:
load()方法用于从服务器上载入XML文件。不过,load()方法只可以载入与包含JavaScript的页面存储于同一服务器上的文件,也就是说,不可以通过其他人的服务器载入XML文件。
还有两种载入文件的模式:同步和异步。以同步模式载入文件时,JavaScript代码会等待文件完全载入后才继续执行代码;而以异步模式载入时,不会等待,可以使用事件处理函数来判断文件是否完全载入了。
默认情况下,文件按照异步模式载入。要进行同步载入,只需设置async特性为false:
然后使用load()方法,并给出要载入的文件名:
执行这一行代码后,oXmlDom会包含能表示XML文件结构的一个DOM文档,这样就可以使用DOM所有的特性和方法了:
异步载入文件时,要使用readyState特性和onreadystatechange事件处理函数:
readyState特性有五种可能的值:
q 0——DOM尚未初始化任何信息;
q 1——DOM正在载入数据;
q 2——DOM完成了数据载入;
q 3——DOM已经可用,不过某些部分可能还不能用;
q 4——DOM已经完全被载入,可以使用了。
一旦readyState特性的值发生变化,就会触发readystatechange事件。如果使用onreadystatechange事件处理函数,就可以在DOM完全载入时,发出通知:
必须在调用load()方法前分配好onreadystatechange事件处理函数,就像下面代码中那样:
无论同步或者异步地载入文件,load()方法都可以接受部分的、相对的或者完整的XML文件路径,如下:
3.获取XML
把XML载入到DOM中后,肯定还需将XML取出来。微软为每个节点(包括文档节点)都添加了一个xml特性,使得这个操作十分方便,它会将XML表现形式作为字符串返回。所以要获取载入后的XML十分简单:
也可以仅获取某个特定节点的XML:
4.解释错误
在尝试将XML载入到XML DOM对象中时,无论使用loadXML()方法还是load()方法,都有可能出现XML格式不正确的情况。为解决这个问题,微软的XML DOM的parseError的特性包含了关于解析XML代码时所遇到的问题的所有信息。
parseError特性实际上是包含以下特性的对象:
q errorCode——表示所发生的错误类型的数字代号(当没有错误时为0);
q filePos——错误发生在文件中的位置;
q line——遇到错误的行号;
q linepos——在遇到错误的那一行上的字符的位置;
q reason——对错误的一个解释;
q srcText——造成错误的代码;
q url——造成错误的文件的URL(如果可用)。
当直接对parseError自身取值,它会返回errorCode的值,也就是说可以这样进行检查:
检查时应该检查错误代码是否不等于0,因为错误代码可能为正也可能为负。
可以使用parseError对象来创建自己的错误对话框:
另一个选项是抛出自己的错误:
不管最终如何显示错误,最好在XML DOM载入完毕后就立即检查错误。
与Mozilla其他方面一样,它提供的XML DOM版本要比IE的更加标准。以下既是在Mozilla如何使用XML
1.创建DOM
DOM标准指出,document.implementation对象有个可用的createDocument()方法。Mozilla严格遵循了这个标准,可以这样创建XML DOM:
createDocument()的三个参数分别是文档的命名空间URL,文档元素的标签名以及一个文档类型对象(总是为null,因为在Mozilla中还没有对文档类型对象的支持)。前面这行代码创建一个空的XML DOM。要创建包含一个文档元素的XML DOM,只需将标签名作为第二个参数:
这行代码创建了代表XML代码<root/>的XML DOM。如果在第一个参数中指定了命名空间URL,可进一步定义文档元素:
2.载入XML
Mozilla只支持一个载入数据的方法:load()。Mozilla中的load()方法和IE中的load()工作方式一样。只要指定要载入的XML文件,以及同步还是异步(默认)载入。
如果同步载入XML文件,代码基本上IE差不多:
进行异步载入,情况就有些不同了。
Mozilla的XML DOM并不支持微软的readyState特性(实际上,readyState并非Mozilla的实现所遵循的DOM Level 3载入和保存规范的一部份)。相反,Mozilla的XML DOM 会在文件完全载入后触发load事件,也就是说必须使用onload事件处理函数来判断DOM何时可用:
Mozilla的XML DOM不支持loadXML()方法。要将XML字符串解析为DOM,必须使用DOMParser对象:
这段代码创建了代表<root/>的XML DOM。第一行创建DOMParser对象,第二行用它唯一的方法parseFromString()来创建XML DOM。这个方法接受两个参数,要解析的XML字符串以及字符串的内容类型。要解析XML代码,内容类型可以是"text/xml"或者"application/ xml";任何其他内容类型都被忽略
因为XML DOM只是Mozilla的JavaScript实现的一部分,所以它可自己添加loadXML()方法。XML DOM实际的类称为Document,所以添加新方法同使用prototype对象一样容易:
然后,用DOMParser创建新的XML DOM:
下面,原来的文档必须清空其内容。可用while循环来删除所有的文档的子节点:
记住,因为这个函数是一个方法,所以this关键词指向XML DOM对象。在删除所有的子节点后,所有的oXmlDom的子节点必须导入到文档中(使用importNode()方法)并作为子节点添加(使用appendChild()):
只需包含这段代码,在Mozilla中就可以与在IE中一样地使用loadXML()方法了。
3.获取XML
Mozilla提供了XMLSerializer对象:
这段简单的代码段用XMLSerializer唯一的方法——serializeTostring()为oXmlDom创建了XML代码。serializeTostring()接受要进行序列化的节点和内容类型作为参数。这次,内容类型可以是"text/xml"或者"application/xml"。使用这个对象,就可以自己为Mozilla合成xml特性,只需使用defineGetter()方法。
defineGetter()方法只存在于Mozilla中,用于为某个特性定义获取函数,也就是说,读取特性时,就会调用这个函数并返回它的结果。例如:
第一行代码读取nodeValue特性,即解释器读取特性的值。如果定义了获取函数,就会运行这个函数并将函数值作为特性的值返回。第二行代码对nodeValue特性进行设置,即为其赋值。如果定义设置函数(与获取函数相对),则调用这个函数,并以New value作为参数值。当然,还有个defineSetter()方法,但在这里用不到。
方法defineGetter()是按照JavaScript对于私有特性和方法的标准隐藏的——在名字前后加上两个下划线:
可以看见,defineGetter()需要两个参数:特性的名称和要调用的函数。指定的特性名不能再用作一般的特性名。例如,不能这样:
一般获取函数和设置函数是成对定义的,但是也可以只分配一个获取函数来创建只读特性。这样就可创建xml特性了。
因为文档中每种类型的节点都有xml特性。所以最好将其添加到Node类中(其他的节点类型都是继承Node的):
分配给xml特性的函数十分简单,对前面的例子的唯一改变是this是serializeToString()方法的第一个参数(在此上下文中,this指向节点自身)。如果将这段代码包含在页面中,就可以与使用微软的xml特性方式一样地使用自定义的xml特性:
4.解析错误
在XML文件的解析过程中发生错误时,XML DOM会创建文档来解释这个错误。假设运行以下代码:
尽管未抛出任何错误,但是oXmlDom会显示出错误。在此例子中,它会呈现出这段代码:
所以要判断是否在XML代码的解析过程中有错误,必须测试文档元素的标签名:
可惜,唯一能获取确切的错误信息的方法是,解析错误信息文本。最简单的方法是使用正则表达式:
这段正则表达式抓取了所有XML代码中潜在的信息。第一个捕获性分组获取错误信息,第二个获取文件名,第三个获取行号,第四个获取列号,第五个获取造成错误的源代码(不包含最后的横线和脱字符号)。只需使用test()方法就可创建错误信息了:
通用接口
有了跨浏览器的解决方案时,使用XML DOM进行开发才真正有用。IE和Mozilla的实现之间有着十分明显的区别,开发时会造成很严重的问题。所以必须找出一套能在两种浏览器中都可使用XML DOM的通用办法。
1.修改DOM创建
第一步是创建IE和Mozilla通用的创建XML DOM对象的方法。最简单的方法是创建伪类,使之可以这样创建XML DOM:
当然,在XmlDom构造函数中必须进行浏览器检测:
这段代码使用了对象/特性检测法来判断要走哪条路。因为Windows上的IE是唯一支持ActiveXObject类的浏览器,所以这样测试IE是可以的。第二种测试比较通用,用于判断浏览器是否支持DOM标准的createDocument()方法。虽然目前只有Mozilla浏览器支持这个方法,但可以预见将来会有其他的浏览器采纳这个功能,所以这样测试确保了代码是经得起未来考验的。
2.IE分支
对于构造函数的IE部分,只需把本书前面的createXMLDOM()函数中的代码插进来即可:
这就是你要对IE所做的。对Mozilla则要做较复杂的事情。
3.Mozilla分支
Mozilla分支的第一步是,用createDocument()方法创建XML DOM对象。
下面的任务是让Mozilla支持readyState特性以及onreadystatechange事件处理函数。这要求必须对Document类再进行一些修改。
首先,添加readyState特性,并初始化为0。
下面,创建onreadystatechange特性,并初始化为null:
一旦readyState特性发生变化,必须调用onreadystatechange函数。为达到这个目的,最好创建一个方法:
这个方法将新状态作为参数并将其分配给readyState特性。注意调用前要先检测onreadystatechange确实是个函数(否则会出现错误)。因为这个方法不能在Document对象外调用,所以使用了JavaScript对于私有方法的标记(前后加上两个下划线)。
IE的XML DOM支持有五种状态,但不可能每种都能在Mozilla中进行模拟。其实,readyState唯一重要的值是4,它表示XML DOM已完全载入并可使用了。这个值可通过onload事件处理函数来模拟。模拟readyState 1也很容易,它表示XML DOM即将开始载入。其他状态不是特别重要,且模拟起来比较困难。
影响到readyState特性的两个方法是,loadXML()和load()。loadXML()方法比较容易更新,因为这是自己创建的方法。只需添加两行代码:
更新后的loadXML()方法最初将readyState设置为1,结束时将其设置为4。
要更新load()方法,首先要创建指向原来方法的引用:
下面,定义新的load()方法,它先将readyState特性设置为1,然后调用原来的load()方法:
要使用onload事件处理函数适时地将readyState设置为4。因为只能在XML DOM对象被实例化之后才能分配事件处理函数,所以必须放在XmlDom构造函数中:
现在,Mozilla的XML DOM就能较好地支持readyState特性(仅对值0、1和4),onreadystatechange事件处理函数,loadXML()方法以及xml特性了。下面的例子可以在IE和Mozilla中使用:
本文地址:http://www.45fan.com/a/question/71999.html