3

次のような構造の 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>

完全なファイルを解析してテーブルに入れる必要があります。(注: eval_d と eval_e には、実際にはそれぞれ 100 を超える属性があります)。MSXML2 を使用してみましたが、ファイルを解析しようとするとスタックします。How to pase XML in VBAおよびParse XML in VBAの回答を使用して、そこにたどり着くことができました。

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

ただし、正しい値を与える代わりに、float in eval_id を 4 回与えます...

ありがとう !

編集: Microsoft Access 2002 SP3 を使用しています

4

1 に答える 1

5

あなたのループはすべて間違っています。カウントループを使用しないでください。必要なことを正確に実行するものが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

ご利用の際は物件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

また、一般論として。これ:

fSuccess = oDoc.Load(Application.CurrentProject.Path & "\file.xml")

の値をチェックしていないように見えるので、実際には必要ではなく、悪い考えでもあります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

複数のサブ/機能を作成することにはいくつかの利点があります

  • すべての関数は 1 つの目的しか持たないため、エラー処理がはるかに簡単になります。
  • 関数の引数でいくつかの変数を定義できるため、必要な変数は少なくなります。
  • 1 つの長い関数よりも 3 つの短い関数の方が何をするかが明確になるため、コードはより保守しやすくなります。
于 2012-07-16T15:05:23.643 に答える