我有一个xml doc,看起来像这样:
<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>
有一个 lot 更多col节点,每个节点包含几千个行元素。
我想解析行元素中的值,并最终将它们放到电子表格中。我目前正在这样做:
' 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文档解析的经验,我正在寻找一种方法同时从'row *'节点中提取所有值,而不必循环遍历它们。这可能吗?
答案 0 :(得分:0)
也许您可以使用 ADO DB Recordset 在Recordset中打开xml DOM文档,然后使用 Range.CopyFromRecordset 方法在添加后将数据转储到Excel中过滤以仅获取您想要的记录?
这是来自MSDN: How to obtain a Recordset from XML
的一些示例代码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
答案 1 :(得分:0)
@chrisSpaceman, 在这里,您可以找到使用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。