浏览器对XML的支持分析

尽管在IE4.0中出现的XML解析器可以做很多事情,但是,存在它的限制。首先,没有办法来在数据源中查找一个指定的数据。为了发现你感兴趣的额数据,你必须遍历整个XML数据树并且手工的进行比较。第二,这些初级的解析器不能提供任何过滤功能,这样你不得不手工进行数据得过滤。

  但是有好消息,好消息是在IE5.0中提供了增强的XML支持用来解决这些用户。IE5.0把解析器集成到了浏览器中,这样就不需要这两个分离得组件了。并且,新得查询语言允许你查询和过滤XML数据。在IE5.0中,查询语言支持是通过一个XSL模式匹配来进行的。IE5.0同时支持XML数据岛的概念,为了在你的Web应用中利用IE5.0的XML解析器,你只要在Web页面中嵌入一个XML数据岛,并利用剧本操作IXMLDOMDocument等DOM接口就可以了。

在XML数据岛中你可以遍历所有的子节点,可以用如下的VBScript语句表示:

<SCRIPT LANGUAGE=vbscript>
   sub traverseChildNodes(nodelist)
    for each node in nodelist
     ' 对该节点做一些操作
     if node.hasChildNodes then
      traverseChildNodes node.childNodes 
     end if
    next
   end sub   sub window_onload()
    traverseChildNodes xmlData.childNodes
   end sub
  </SCRIPT>

  在IE5.0中,增加了两个新的DOM方法:selectNodes和selectSingleNode。这两个方法都采用一个模式字符串作为唯一的输入参数,selectNodes返回一个对IXMLDOMNodeList的引用,而selectSingleNode返回一个对IXMLDOMNode的引用。两个方法唯一的不同是selectNodes返回所有匹配的节点,而selectSingleNode只返回符合匹配模式的第一个节点。

  下面是使用selectNodes方法遍历XML数据岛的所有订货项目的例子:

<SCRIPT LANGUAGE=vbscript>
   sub traverseAllOrderItems(ordernode)
    set nodelist = ordernode.selectNodes("//item")
    for each node in nodelist
     ' 这里可以对节点进行一些处理
    next
   end sub   sub window_onload()
    traverseAllOrderItems xmlData.documentElement
   end sub
  </SCRIPT>

  传递给方法selectNodes的字符串//item是模式的一个例子,事实上,你可以对任何IXMLDOMNode 对象调用selectNodes或者是selectSingleNode方法。

  在具体查询的时候,你可以把新的查询语言应用到XSL模板上。模式可以被用来匹配和选择在XSL中的属性,需要注意的是,缺省的XSL模板指定匹配XML文档的根节点(/)。上面的代码for-each循环只对订单项目进行操作。

  我们知道,XML被设计成在一个层次格式中描述数据的结构,一个XML文档包括一个单一的根节点,它能够包含多个子节点,在XML文档中的任何的根节点也可以包含更多的子节点,当然也可以不包含子节点。因此,XML实际上是以树的形式来组织数据的。

  XSL模式匹配语言提供了遍历一个XML文档树结构的语义。XSL模式匹配语言有点象在文件系统外壳下,遍历文件系统。比如你在C盘的根目录下键入:

  cd windows\system32

  当前的目录将转换成c:\windows\system32,XSL模式匹配语言基本上以相同的方式进行工作。比如,一个模式orders/order/item表示在orders元素下的order元素下的item元素。这个匹配是在当前节点的上下文下进行解析的。

  调用selectNodes 和selectSingleNode的节点变成当前节点。前面在讲述XSL标准的时候,已经提到,在一个匹配模式前面加上"/",表示模式匹配是丛根节点开始的,用"./"表示从当前的节点开始匹配。用"//"表示对在节点下的所有子节点进行匹配,不管它在那个层上。你也可以使用"*"来匹配所有的元素。你也可以使用"@"符号来执行一个给定元素的属性。比如,为了识别项目元素的类型属性,可以采用下面的匹配模式:

file://item/@type

  一般来说,你可以把属性当成是元素的子节点。除非在名字前面加上了符号"@"集合。在这里讨论的基本匹配模式能够识别元素的集合,比如匹配模式//item指定了一个项目元素的集合,该集合可能存在于文档的任何位置。因为你需要在一个集合内找出特定的元素,模式匹配提供了一个标准的操作符"[]",表示对一个集合的索引。该索引是从0开始的。比如匹配模式//item/price[0]表示每一个项目元素的第一个价格元素。而模式//item[0]/price[0]表示在所有的项目集合中的第一个项目元素的第一个价格元素。同时需要注意的是,可以用括号对操作进行分组。

  下面我们讨论一下过滤模式,过滤模式也包含了表达式用来指定如何在一个集合中对项目进行过滤。实际上存在许多操作符,你可以使用它们来创建过滤表达式,这些操作符允许你创建标准的比较表达式,逻辑表示式和集合表达式。一般来说,操作符的起始和结尾都用"$"符号表示,其中很多符号都是借用了C++中的符号表示,比如下面的两个表达式是等价的:

file://item[index() >= 3]
  file://item[index() $ge$ 3]

  下面我们来分析一个相对比较复杂的过滤表达式:

  (orders//order[customer/lastname $ieq$ "Skonnard" && @itemcount > 1]/ item[price > 20])[index() < 10]

  这个表达式表示从满足条件的集合中选择前十个订单,这个条件就是价格大于20美金,订单的客户的姓是Skonnard,并且他的订单数超过一个。从这个表达式中你可以发现,利用过滤表达式你可以做非常复杂和精确的查询。

  必须要指出的是,IE是第一个提供高级XML支持的浏览器,为了充分利用IE浏览器的性能,你必须熟悉XSL模式匹配语言的语义并且在执行复杂查询和过滤操作的时候使用它们。