如何用VBA解析XML问题,怎么解决

XML也是储存数据的一种常用形式,这节来看下从XML文件中取数据的一般方法。

一般来说,如果你的XML文件结构比较规整的话可以用Excel自带的功能来直接导入XML形式的文件,在开发工具菜单XML组中找导入,非常方便,今天我们主要来看怎样用VBA来处理XML文件。

现在我手上有一个名为Rawdata.xml的XML文件,现在我想要把该文件中所有的数据都取到Excel中,直接看代码

Private Sub OpenXml1()

Dim objDOM, n, nodes As Object, ns, i, j

Set objDOM = CreateObject("MSXML.DOMDocument")

objDOM.Load (ThisWorkbook.Path & "\Rawdata.xml")

objDOM.async = False

Set ns = objDOM.SelectNodes("//extraction") '取节点extraction,即行

Set n = objDOM.SelectSingleNode("//extraction") '取单个Extraction,其长度即列

For i = 1 To ns.Length

For j = 1 To n.ChildNodes.Length

Cells(i, j) = ns.Item(i - 1).ChildNodes(j - 1).Text

Next

Next

Debug.Print n.ChildNodes.Length

Debug.Print ns.Length

Debug.Print ns.Item(0).Text

Set objDOM = Nothing

End Sub

代码稍微解释一下,先建立一个DOM对象,然后用Load方法将XML文件内容载入。选取节点用的是SelectNodes,该XML文件中行标签是extraction,所以我选择了该节点,那节点的个数就是行数了。获得单个节点的结构用的是SelectSingleNode,那这单个节点中子节点的个数n.ChildNodes.Length就是列数了。ns.Item(i).ChildNodes(j).text就是节点集ns中第i项的第j个子节点的值,我们要的内容也就取出来了。

那如果我不要取所有的列,只想取某几列,那怎么办,看代码

Private Sub OpenXml2()

Dim objDOM, n, ns, i, j, strh(), arr()

Cells.Clear

strh = Array("tdx", "tda", "tdb", "tdc", "tdk", "tdl", "tdy", "tdm", "tdn", "tdo", "tdp", "tdq", "tdu", "tdv", "td1", "new1", "new2")

Set objDOM = CreateObject("MSXML.DOMDocument")

objDOM.Load (ThisWorkbook.Path & "\Rawdata.xml")

objDOM.async = False

'MsgBox objDOM.XML

Set ns = objDOM.SelectNodes("//extraction")

Set n = objDOM.SelectSingleNode("//extraction")

ReDim arr(1 To ns.Length, 1 To UBound(strh) + 1)

For i = 1 To ns.Length

For j = 1 To UBound(strh) + 1

On Error Resume Next

arr(i, j) = ns.Item(i - 1).GetElementsByTagname(strh(j - 1)).Item(0).Text

Next

Next

Set ns = Nothing

Set n = Nothing

Set objDOM = Nothing

Range("A1").Resize(UBound(arr), UBound(strh) + 1) = arr

End Sub

上面的代码就是取以"tdx", "tda", "tdb", "tdc", "tdk", "tdl", "tdy", "tdm", "tdn", "tdo", "tdp", "tdq", "tdu", "tdv", "td1", "new1", "new2"为标签的列,和前面不同的主要是这句ns.Item(i - 1).GetElementsByTagname(strh(j - 1)).Item(0).Text,用getelementsbytagname(节点名)取节点,ns.Item(i-1)是行节点的第n-1项,从这项中用GetElementsByTagname取出相应的列节点,一般来说到列了不会有多项了,所以我们直接用第1项(下标是0)的值来表示我们要的结果,之间的层层关系自己体会一下。