将多个xml节点提取到数组中而不循环

我有一个XML文件,看起来像这样:

<rng> <col1> <row1>A</row1> <row2>B</row2> <row3>C</row3> <row4>D</row4> </col1> <col2> <row1>E</row1> <row2>F</row2> <row3>G</row3> <row4>H</row4> </col2> </rng> 

col节点有很多 ,每个包含几千行元素。

我想parsing出行元素的值,并最终把它们放到电子表格上。 我目前正在这样做,如下所示:

 ' get a list of the col elements (thi sits in a loop to go through them all) Set oXMLColNodeList = oXMLDoc.selectNodes("//saveStates/rng/*") ' Lop through each column For colNum = 1 To oXMLColNodeList.Length ' get all the row nodes for that coulmn Set oXMLRowNodeList = oXMLDoc.selectNodes("//saveStates/rng"/col" & colNum & "/*") ' loop through all the row nodes For rowNum = 1 To oXMLRowNodeList.Length ' get the node to do something with it Set oXMLNode = oXMLDoc.selectSingleNode("//saveStates/rng/col" & colNum & "/row" & rowNum) next rowNum next colNum 

也就是说,我遍历col节点,然后遍历每个行节点以获取值A,B,C,D等。当行元素的数量达到数万时,这是灾难性的缓慢。

我没有太多的XML文档parsing经验,我正在寻找一种方法来同时从“row *”节点中提取所有的值,而不必循环遍历它们。 这可能吗?

也许你可以使用ADO数据库logging集打开logging集中的XML DOM文档,然后使用Range.CopyFromRecordset方法将数据转储到Excel后,添加一个filter只获取你想要的logging?

这里是一些来自MSDN的示例代码:如何从XML获取Recordset

 Public Function RecordsetFromXMLDocument(XMLDOMDocument As DOMDocument) As Recordset Dim oRecordset As ADODB.Recordset dim destRange as range set destrange=range("B2") Set oRecordset = New ADODB.Recordset oRecordset.Open XMLDOMDocument 'pass the DOM Document instance as the Source argument Set RecordsetFromXMLDocument = oRecordset 'return the recordset destRange.CopyFromRecordset oRecordset Set oRecordset = Nothing End Function 

@chrisSpaceman,在这里你可以find使用XMLDOM的更简单的方法。 我添加了一些声明为了显示一个完整的例子(我假设你知道如何操作数组,所以我把它留在旁边)。

 Option Explicit Sub ReadRows() 'Declarations Dim oXMLDoc As Object ' XML document (object) 'Dim oXMLColNodeList As Object ' you don't need this list any more ! Dim oXMLRowNodeList As Object ' needed node list Dim oXMLNode As Object ' single node within this list Dim xPE As Object ' ParseError object Dim strErrText As String ' Error message Dim sFileName As String ' user defined file path ' ================================= ' 0. User defined File Name <== ! ' ================================= sFileName = ThisWorkbook.Path & "\data\test.xml" ' ================================= ' 1. XML Declaration oXMLDoc ' ================================= ' Set oXMLDoc = New MSXML2.DOMDocument60 ' Early Binding Set oXMLDoc = CreateObject("Msxml2.DOMDocument.6.0") ' Late Binding ' XPath, Validation oXMLDoc.setProperty "SelectionLanguage", "XPath" oXMLDoc.validateOnParse = False ' ================================= ' 2. Load XML File ' ================================= If oXMLDoc.Load(sFileName) Then MsgBox sFileName & " successfully loaded" Else ' Set ParseError Object Set xPE = oXMLDoc.parseError With xPE strErrText = "Load Error " & .ErrorCode & " XML File " & vbCrLf & _ Replace(.URL, "file:///", "") & vbCrLf & vbCrLf & _ xPE.reason & _ "Source Text: " & .srcText & vbCrLf & vbCrLf & _ "Line No: " & .Line & vbCrLf & _ "Line Pos: " & .linepos & vbCrLf & _ "File Pos: " & .filepos & vbCrLf & vbCrLf End With MsgBox strErrText, vbExclamation Set xPE = Nothing Set oXMLDoc = Nothing 'Stop procedure Exit Sub End If ' ================================= ' 3 Set only one Nodelist ' ================================= Set oXMLRowNodeList = oXMLDoc.DocumentElement.SelectNodes("rng/*/*") ' ================================= ' 4. loop through all (row) nodes ' ================================= For Each oXMLNode In oXMLRowNodeList Debug.Print oXMLNode.Text ' read in ... Next oXMLNode ' 5. terminate oXMLDoc Set oXMLDoc = Nothing End Sub 

备注这段代码避免了太多的循环,只通过通配符设置一个NodeList到col标签(因为col和row节点没有兄弟)。 此外,我会引用DocumentElement而不是使用// saveStates,如果这实际上代表您的根节点。