Est*_*ius 3 ms-access vba msxml access-vba xml-parsing
我有一个XML文件,其结构类似于:
<egh_eval>
<eval_set>
<eval_id>FLOAT</eval_id>
<eval_d>
<height>INT</height>
<weight>INT</weight>
</eval_d>
<eval_e>
<height>INT</height>
<weight>INT</weight>
</eval_e>
<eval_cred>
<credit>FLOAT</credit>
</eval_cred>
</eval_set>
Run Code Online (Sandbox Code Playgroud)
我需要解析完整的文件并将其放在表格中.(注意:eval_d和eval_e实际上每个都有超过一百个属性).我尝试使用MSXML2,但是当我尝试解析文件时,我遇到了问题.通过使用在回答如何在VBA填写Flash XML和VBA中解析XML我能到那里:
Dim fSuccess As Boolean
Dim oDoc As MSXML2.DOMDocument
Dim oRoot As MSXML2.IXMLDOMNode ' Level 0 egh_eval
Dim oChild As MSXML2.IXMLDOMNode ' Level 1 eval_set
Dim oChildren As MSXML2.IXMLDOMNode ' Level 2 eval_id, eval_d, eval_e, eval_cred
Dim domList As MSXML2.IXMLDOMNodeList
Set oDoc = New MSXML2.DOMDocument
oDoc.async = False
oDoc.validateOnParse = False
fSuccess = oDoc.Load(Application.CurrentProject.Path & "\file.xml")
Set oRoot = oDoc.documentElement
Set oChild = oRoot.childNodes(0)
Set oChildren = oChild.childNodes(0)
For i = 0 To oChild.childNodes.length - 1
For y = 0 To oChildren.childNodes.length - 1
MsgBox oChildren.nodeName & " : " & oChildren.nodeTypedValue
oChildren.childNodes.nextNode
Next
oChild.childNodes.nextNode
Next
Run Code Online (Sandbox Code Playgroud)
但是,它没有给我正确的值,而是让我在eval_id中浮动4次...
谢谢 !
编辑:我正在使用Microsoft Access 2002 SP3
你的循环都错了.不要使用计数循环.有For Each哪些将完全满足您的需求,而且它的可读性也更高.
Dim egh_eval As MSXML2.IXMLDOMNode
Dim eval_set As MSXML2.IXMLDOMNode
Dim eval_prop As MSXML2.IXMLDOMNode
Set egh_eval = oDoc.documentElement.childNodes(0)
For Each eval_set In egh_eval.childNodes
If eval_set.nodeType = NODE_ELEMENT Then
For Each eval_prop In eval_set.childNodes
If eval_prop.nodeType = NODE_ELEMENT Then
MsgBox eval_prop.nodeName & " : " & eval_prop.childNodes.length
End If
Next eval_prop
End If
Next eval_set
Run Code Online (Sandbox Code Playgroud)
使用childNodes时必须检查nodeType酒店.注释,文本节点等都将在子节点列表中,而不仅仅是元素节点.
考虑使用XPath来选择元素可能是个好主意.使用DOM方法执行此操作容易出错并且很麻烦.阅读IXMLDOMNode::selectNodes和IXMLDOMNode::selectSingleNode.
For Each eval_set In oDoc.selectNodes("/egh_eval/eval_set")
Set eval_id = eval_set.selectSingleNode("eval_id")
' always check for empty search result!
If Not eval_id Is Nothing Then
MsgBox eval_id.text
' ...
End If
Next eval_set
Run Code Online (Sandbox Code Playgroud)
另外,一般情况下.这个:
fSuccess = oDoc.Load(Application.CurrentProject.Path & "\file.xml")
Run Code Online (Sandbox Code Playgroud)
实际上既不是必要的也不是一个坏主意,因为你似乎永远不会检查它的价值fSuccess.更好:
Sub LoadAndProcessXml(path As String)
Dim oDoc As MSXML2.DOMDocument
If oDoc.Load(path) Then
ProcessXmlFile oDoc
Else
' error handling
End If
End Sub
Sub ProcessXml(doc As MSXML2.DOMDocument)
' Process the contents like shown above
End Sub
Run Code Online (Sandbox Code Playgroud)
创建多个子/函数有几个优点