4

我正在努力让 excel 解析一个 xml 文件。我找到了很多例子,但似乎没有一个是我正在寻找的,而且我似乎无法克服错误“对象变量或未设置块变量”

xml 格式正确,如下所示:

<xml tag>
<PLMXML>
  <WorkflowTemplate name="">
    <argument name="">
    </argument>
  </WorkflowTemplate >
  <WorkflowTemplate name="">

等等

我正在尝试使用 VBA 来单独获取所有儿童名称的值并获取参数的名称。我一直收到此代码的错误:

Dim xmlDoc As MSXML2.DOMDocument
Dim xmlElement As MSXML2.IXMLDOMElement
Dim xmlNode As MSXML2.IXMLDOMNode
Dim xmlAttribute As MSXML2.IXMLDOMAttribute

Set xmlDoc = New MSXML2.DOMDocument
xmlDoc.async = False
xmlDoc.validateOnParse = False

'ENTER THE PATH WHERE THE XML Workflow DOCUMENT IS STORED:
Dim DocumentPath As String
DocumentPath = InputBox("Enter the full path for the xml workflow document, example: C:\workflows\workflowseasy.xml", "Workflow XML File path", "C:\workflows\workflowseasy.xml")
xmlDoc.Load (DocumentPath)

Set xmlElement = xmlDoc.DocumentElement

Set xmlNode = xmlElement.SelectSingleNode("WorkflowTemplate[0]")


Set xmlAtribute = xmlNode.Attributes.getNamedItem("name")

我不清楚如何在 excel vba 中使用此解析器获取文档中的数据。任何帮助将不胜感激。我目前在参考文献中选择了 Microsoft XML,v6.0。

更新

我一直在深入研究它并提出了以下代码,尽管我仍然遇到同样的错误:

Dim xmlDoc As MSXML2.DOMDocument60
Dim xmlRoot As MSXML2.IXMLDOMNode
Dim xmlTemplate As MSXML2.IXMLDOMNode
Dim xmlAttributes As MSXML2.IXMLDOMNamedNodeMap
Dim xmlName As MSXML2.IXMLDOMNode
Dim xmlChildren As MSXML2.IXMLDOMNodeList
Dim xmlChild As MSXML2.IXMLDOMNode
Dim intI As Long
intI = 1

Set xmlDoc = New MSXML2.DOMDocument60
xmlDoc.async = False
xmlDoc.validateOnParse = False

'ENTER THE PATH WHERE THE XML Workflow DOCUMENT IS STORED:
Dim DocumentPath As String
DocumentPath = InputBox("Enter the full path for the xml workflow document, example: C:\workflows\workflowseasy.xml", "Workflow XML File path", "C:\workflows\workflowseasy.xml")
xmlDoc.Load (DocumentPath)

Set xmlRoot = xmlDoc.DocumentElement *****these say they are empty when debugging
Set xmlChildren = xmlRoot.ChildNodes *****these say they are empty when debugging
For Each xmlTemplate In xmlChildren  *****error occures here
    If xmlTemplate.nodeName = "WorkflowTemplate" Then
    Set xmlAttributes = xmlTemplate.Attributes
    Set xmlName = xmlAttributes.getNamedItem("name")
    ActiveSheet.Cells(int1, 1).Value = xmlName.Text
    Set xmlChildren = xmlTemplate.ChildNodes
    intI = intI + 1
    End If
Next xmlTemplate

最后更新* *

弄清楚了。文件的加载是问题所在。由于某种原因,从 msg 框中传递字符串不起作用,但从 gui 文件选择器传递它可以。这是我最终使用的代码。

    Dim xmlDoc As MSXML2.DOMDocument60
Dim xmlRoot As MSXML2.IXMLDOMNode
Dim xmlTemplate As MSXML2.IXMLDOMNode
Dim xmlAttributes As MSXML2.IXMLDOMNamedNodeMap
Dim xmlName As MSXML2.IXMLDOMNode
Dim xmlChildren As MSXML2.IXMLDOMNodeList
Dim xmlChild As MSXML2.IXMLDOMNode
Dim intI As Long
intI = 1

Set xmlDoc = New MSXML2.DOMDocument60
xmlDoc.async = False
xmlDoc.validateOnParse = False

'ENTER THE PATH WHERE THE XML Workflow DOCUMENT IS STORED:
Dim DocumentPath As String
With Application.FileDialog(msoFileDialogOpen)
.Title = "Choose File"
.AllowMultiSelect = False
.Show
'DocumentPath.Show
DocumentPath = .SelectedItems(1)
End With

xmlDoc.Load (DocumentPath)

Set xmlRoot = xmlDoc.DocumentElement
Set xmlChildren = xmlRoot.ChildNodes
For Each xmlTemplate In xmlChildren
    If xmlTemplate.nodeName = "WorkflowTemplate" Then
    Set xmlAttributes = xmlTemplate.Attributes
    Set xmlName = xmlAttributes.getNamedItem("name")
    ActiveSheet.Cells(int1, 1).Value = xmlName.Text
    Set xmlChildren = xmlTemplate.ChildNodes
    intI = intI + 1
    End If
Next xmlTemplate

目前,代码在分配值部分中断,但通过代码,变量正在提取正确的值并正确提取 xml 信息。

4

1 回答 1

2

我认为问题中提供的最终代码可能并不总是遍历整个 xml 文档,因为 xmlChildren 变量在循环期间被覆盖,所以我认为这可能只是获得第一个子节点,它是第一个子节点,依此类推。

要遍历整个文档,您可以调用一个单独的过程并构建一个递归调用,以便它将跟随每个子节点,然后在完成后返回到调用它的列表。

这是一个简化的示例,我正在查找特定 xml 元素的所有实例,例如包含以下内容的 xml 文档中的所有购物车:

<?xml version="1.0" encoding="UTF-8"?>
<ImportConfig>
    <ShoppingCarts description="Any carts added here will be picked up by the auto import">
        <cart>shopping cart 1 name here</cart>
        <cart>shopping cart 2 name here</cart>
    </ShoppingCarts>
</ImportConfig>

下面的第一个过程是针对此示例的,即标记的名称等,但其他两个可以一般用于任何 xml 文档(第一个只是如何使用它们的示例):

' Chris Prosser 09/07/2014
' example use of getElementList (in this case to get all cart elements)

Sub getCarts()
    Dim carts As Collection
    Dim i As Integer

    Set carts = New Collection
    getElementList "C:\Users\Chris\Dropbox\VBAutomation\AutoImportConfig.xml", "cart", carts

    For i = 1 To carts.count
        Debug.Print carts.Item(i)
    Next

End Sub

' Chris Prosser 09/07/2014
' Gets the values of all instances of a specific element from an xml file

Sub getElementList(xml_file_path As String, _
                          elementName As String, _
                          elementValuesList As Collection)

    Dim xmlDoc As MSXML2.DOMDocument
    Dim xmlRoot As MSXML2.IXMLDOMNode
    Dim xmlChildren As MSXML2.IXMLDOMNodeList
    Dim xmlElement As MSXML2.IXMLDOMElement

    Set xmlDoc = New MSXML2.DOMDocument
    xmlDoc.async = False
    xmlDoc.validateOnParse = False
    xmlDoc.Load (xml_file_path)
    Set xmlRoot = xmlDoc.documentElement
    Set xmlChildren = xmlRoot.childNodes

    iterateOverChildNodes xmlChildren, elementName, elementValuesList

End Sub

' Chris Prosser 09/07/2014
' Call with a list of xmlNodes (can be generated from a file using getElementList)
' and an element name to search for. The procedure find child nodes and re-runs
' recursively until all branchs from the list of nodes passed in have been traversed

Sub iterateOverChildNodes(xmlChildren As MSXML2.IXMLDOMNodeList, _
                          elementName As String, _
                          elementValuesList As Collection)

    Dim xmlElement As MSXML2.IXMLDOMElement
    Dim xmlGrandChildren As MSXML2.IXMLDOMNodeList

    For Each xmlElement In xmlChildren
        If xmlElement.nodeName = elementName Then
            'Debug.Print xmlElement.nodeTypedValue
            elementValuesList.Add xmlElement.nodeTypedValue
        Else
            Set xmlGrandChildren = xmlElement.childNodes
            iterateOverChildNodes xmlGrandChildren, elementName, elementValuesList
        End If
    Next xmlElement

End Sub
于 2014-07-09T21:04:06.157 回答