ExcelTip.Net留存知识帖 ---【注:附件之前被网盘供应商清空后,现已修复-现已修复-现已修复为本地下载!】
现在位置:首页 > E文精选 > Excel VBA > 如何运用VBA调用XMLDOM对象对XML文档节点进行查询以及XPATH语法基础概要

如何运用VBA调用XMLDOM对象对XML文档节点进行查询以及XPATH语法基础概要

作者:绿色风 分类: 时间:2022-08-17 浏览:318
楼主
xmyjk
    讲完XML文档的语法基础(http://www.exceltip.net/thread-33576-1-1.html
),我们开始讲XML文档的节点查询,这就要我们开始了解XML DOM了。XML DOM定义了所有 XML 元素的对象和属性以及方法。之前,我们先复习几个概念,以及在此复习下XML文档树。

(1)节点:文档的每个结构,都是节点。例如,整个文档是文档节点;每个标签是元素节点;每个属性是属性节点;每个元素中的文本是文本节点。总之,能统统都是节点,呵呵。但是要注意,和HTML概念不一样,元素节点并不包含文本,而是元素节点的文本是储存在文本节点里面的!例如,<id>xmyjk</id>,xmyjk并不是id元素的值,而是id元素节点,拥有一个值为“xmyjk”的文本节点(用text()表示)。另外,属性也是节点,与元素节点不同,属性节点拥有文本值。

(2)元素:元素是起始标签和结束标签之间的文档内容。元素对象只是节点的一种,可以认为节点>元素。一定要把元素和节点这两个概念分清楚,特别是学过HTML的同学。

(3)节点树:以以下代码为例:
<?xml version="1.0"?>
<memberlist>
   <member Uid="30639" timer="952" nicheng="上旋下弦月">
         <id>xmyjk</id>
         <city>厦门</city>
         <group>开心队</group>
   </member>
   <member Uid="56305" timer="529">
        <id>xyf2210</id>
        <city>浙江</city>
        <group>开心队</group>
   </member>
   <member Uid="33175" timer="3398">
         <id>海洋之星</id>
         <touxian>ET高级认证讲师</touxian>
         <city>西安</city>
         <group>腾龙队</group>
   </member>
   <member Uid="41613" timer="3122">
        <id>Zaezhong</id>
        <touxian>ET认证讲师</touxian>
        <city>未知</city>
        <group>腾龙队</group>
   </member>
   <member Uid="85249" timer="481">
         <id>Rongson_Chart</id>
         <city>未知</city>
         <group>A.C.E战队</group>
   </member>
   <member Uid="15819" timer="1279">
        <id>無心</id>
        <touxian>ET认证讲师</touxian>
        <city>未知</city>
        <group>A.C.E战队</group>
   </member>
</memberlist>


节点树的图形如下:

 

    如图,memberlist就是根节点,member元素就是它的子节点,层层递推。另外,属性节点,和文本节点也是相关元素节点的子节点。通过这个节点树,我们可以运用xml dom访问所有的节点,甚至可以修改或删除它们,以及创建新元素。

    EXCEL VBA中,我们也可以用多种方式去解析xml文档,这里仅仅介绍用xmldom对象去解析。我们仅仅用以下几行代码,即可加载xml文档到xmldom对象中:
  1. Sub test1()
  2.     Dim XmlDom, i As Integer
  3.    
  4.     Set XmlDom = CreateObject("Microsoft.XMLDOM") '创建xmldom对象
  5.     XmlDom.async = False '设置不允许异步处理
  6.     XmlDom.Load 地址 '加载xml文档
  7. End Sub
加载完毕后,我们怎么去查找我们需要的节点呢?我总结了一下,主要有以下两种:
  
  (1)使用经典的DOM-属性和方法
   
    经典方法:
      .getElementsByTagName(name) - 获取带有指定标签名称的所有元素
      .getNamedItem(name) – 仅用于获取指定名称的属性节点
      .getAttribute(name) - 获取指定名称的属性节点的值
      .getAttributeNode(name) – 获取指定名称的属性节点
   
    经典属性:
      .parentNode -父节点
      .childNodes -子节点
      .firstChild – 第一个节点
      .lastChild – 最后一个节点
      .attributes -属性节点
      .nodeValue – 文本节点的文本值或属性节点的属性值
      .Text 元素节点中包含的文本
  1. Sub test1()
  2.     Dim XmlDom, i As Integer, XmlNodes, xmlnd
  3.    
  4.     Set XmlDom = CreateObject("Microsoft.XMLDOM") '创建xmldom对象
  5.     XmlDom.async = False '设置不允许异步处理
  6.     XmlDom.Load ThisWorkbook.Path & "\1.xml" '载入xml文档
  7.     Set XmlNodes = XmlDom.getElementsByTagName("id") '查找所有ID元素节点
  8.     Debug.Print XmlNodes.Length '看看获取了多少个ID元素
  9.     Debug.Print XmlNodes(0).childnodes(0).nodevalue '获取xmyjk节点文本
  10.     Debug.Print XmlNodes(0).Text '获取xmyjk节点文本第二种方法
  11.     Debug.Print XmlDom.getElementsByTagName("member")(0).Attributes.getnameditem("timer").nodevalue '获取属性第一种方法
  12.     Debug.Print XmlDom.getElementsByTagName("member")(0).getAttribute("timer") ''获取属性第2种方法
  13.     Debug.Print XmlDom.getElementsByTagName("member")(0).getAttributeNode("timer").nodevalue ''获取属性第3种方法
  14.     For Each xmlnd In XmlNodes '历遍
  15.        Debug.Print xmlnd.Text
  16.     Next
  17. End Sub
特别注意XmlNodes(0).childnodes(0).nodevalue这句,XmlDom.getElementsByTagName("id")获得的xmlnodes是,xml文档的所有的id的节点列表,那第一个id的节点就是包含xmyjk这个文本的id节点,这个id节点的第一个子节点就是xmyjk这个文本节点,这个文本节点的nodevalue就是xmyjk。
   
    那.text指的就是,元素节点里面包含的文本,因此可以直接跟在元素节点后面使用。得出的结果一样是xmyjk。
   
    元素节点下属的属性节点列表,可以用attributes去获取,再用.getnameditem方法去获取相应名称的属性节点,而后取值。也可以直接使用. getAttribute获取属性,或者也可以直接使用.getAttributeNode去获取属性节点再用nodevalue取值。
   
    最后,节点也是可以用FOR EACH去枚举历遍的,和VBA里面的对象历遍都是一样的。

(2)运用xpath与selectNodes()/selectSingleNode()结合
   
    XPath 是一门在 XML 文档中查找信息的语言,它使用路径表达式在 XML 文档中进行导航,类似我们的文件系统的路径表达式。XPATH选取节点的路径表达式的语法(引用了W3SCHOOL的图片表达):

 
   
    /和我们的文件路径很像,例如:memberlist/member。//就表示在所有路径中查找,例如//id就表示查找所有的id元素节点。
   
    另外,就如SQL的WHERE查询一样,我们也可以设定我们的查询条件,可以用中括号[]来书写条件。例如:memberlist/member[last()-2]这样查找member节点列表的倒数第3个member节点。

    @是专门用来查找属性节点的,例如,用来查找所有timer的属性节点,就用//@timer表示。@一样也可以在[]内使用,例如: //member[@nicheng]可以用于查找,拥有nicheng属性的member节点。
   
    甚至,我们还可以使用node()(匹配任何节点),*(匹配任何元素节点),text()(匹配任何文本节点),@*(匹配任何属性节点)这样的模糊或者类型匹配查询。
   
    最后,我们还可以使用“|”去使用多路径查找。在判断条件里面,我们还可以运用and 或者 or 或者!=等等运算符。案例请看下面的代码。
  1. Sub test2()
  2.     Dim XmlDom, i As Integer, XmlNodes, xmlnd
  3.    
  4.     Set XmlDom = CreateObject("Microsoft.XMLDOM") '创建xmldom对象
  5.     XmlDom.async = False '设置不允许异步处理
  6.     XmlDom.Load ThisWorkbook.Path & "\1.xml" '载入xml文档
  7.     Set XmlNodes = XmlDom.SelectNodes("memberlist/member") '获取所有的member元素节点
  8.     Debug.Print XmlNodes(0).Text '输出第一个member节点的文本
  9.     Set XmlNodes = XmlDom.SelectNodes("//id") '获取所有的id元素节点
  10.     Debug.Print XmlNodes(0).Text '输出第一个id节点的文本
  11.     Set XmlNodes = XmlDom.SelectNodes("//@timer") '获取所有的timer属性节点
  12.     Debug.Print XmlNodes(0).Value '输出第一个timer属性节点的值
  13.     Set XmlNodes = XmlDom.SelectNodes("//member[@nicheng]") '获取拥有nicheng属性的member节点
  14.     Debug.Print XmlNodes(0).Text '输出匹配的第一个节点的文本
  15.     Set XmlNodes = XmlDom.SelectNodes("//member[@timer>1000]/id") '获取拥有timer属性大于1000的member节点的id元素
  16.     Debug.Print XmlNodes(0).Text '输出匹配的第一个节点的文本
  17.     Set XmlNodes = XmlDom.SelectNodes("//member[city='厦门'] | //member[city='浙江']") '获取city=厦门或浙江的member节点
  18.     Debug.Print XmlNodes(1).Text '输出匹配的第二个节点的文本
  19.     Set XmlNodes = XmlDom.SelectNodes("//member[group='腾龙队' and city='未知']") '获取city=未知和组别是腾龙队的member节点
  20.     Debug.Print XmlNodes(0).Text '输出匹配的第二个节点的文本
  21.     Set XmlNodes = XmlDom.SelectSingleNode("//city[text() = '厦门']").ParentNode  '获取city元素节点的下属文本节点是厦门的member节点
  22.     Debug.Print XmlNodes.XML '输出匹配的xml代码
  23. End Sub

xml文件.zip
xmldomvba.rar
2楼
eliane_lei
进来学习VBA
3楼
水星钓鱼
好文,推荐阅读。
4楼
cainleo
跟着文档说明操作了,但是由于个人水平问题,两个宏究竟要起到什么作用实在理解不了。
另外想确认能否实现一下功能:通过excel载入、修改xml文件,以达到修改xml文件中部分节点的信息的目的?
5楼
E林好汉
在vba中能否提示一下须用户自己修改的地方?
6楼
波罗密
多谢
7楼
skyboyhxc
VBA 很多年不碰了 不怎么习惯啊

免责声明

有感于原ExcelTip.Net留存知识的价值及部分知识具有的时间限定性因素, 经与ExcelTip.Net站长Apolloh商议并征得其同意, 现将原属ExcelTip.Net的知识帖采集资料于本站点进行展示, 供有需要的人士查询使用,也慰缅曾经的论坛时代。 所示各个帖子的原作者如对版权有异议, 可与本人沟通提出,或于本站点留言,我们会尽快处理。 在此,感谢ExcelTip.Net站长Apolloh的支持,感谢本站点所有人**绿色风(QQ:79664738)**的支持与奉献,特此鸣谢!
------本人网名**KevinChengCW(QQ:1210618015)**原ExcelTip.Net总版主之一

评论列表
sitemap