VBA中的XML解析

时间:2016-12-19 12:42:15

标签: vba xml-parsing

我在解析从API返回的XML时遇到了麻烦。我的主要观点是使用"使用"和"限制"其中一个节点的属性(使用xPath)。

现在我甚至无法探索整个XML树,所以我来这里寻求帮助

返回的XML如下所示:

 <?xml version="1.0" encoding="UTF-8"?>
<QueryResultRecords xmlns="http://www.xmlns.loc/sub" type="application/some.app.query+xml" href="https://my.api.call.com/query?has_cheezburger" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.xmlns.loc/sub http://my.api.address.com/schema/master.xsd">
    <OnlyNodeType Name="name1" link="hhttp://my.api.address.com/a5d11b73dffe" Used="240640"  Limit="0"  />
    <OnlyNodeType Name="name2" link="http://my.api.address.com/03b11042ccd4"  Used="10240"  Limit="409600" />
    <OnlyNodeType Name="name3" link="http://my.api.address.com/1cf43be18e2e"  Used="11934947"  Limit="20971520" />
</QueryResultRecords>

我粗略地理解XMLDom在VBA中是如何工作的,但是在网上搜索,我设法写了这个,这显然不起作用......

Dim XMLDOC As MSXML2.DOMDocument60
Dim nodelist As IXMLDOMNodeList
Set XMLDOC = New MSXML2.DOMDocument60
XMLDOC.async = False
XMLDOC.validateOnParse = False
XMLDOC.Load (myhttpresponse)

Namespace = "xmlns: 'http://www.xmlns.loc/sub' "
Call XMLDOC.setProperty("SelectionNamespaces", Namespace)
Call XMLDOC.setProperty("SelectionLanguage", "XPath")

XPath = "/"

Set nodelist = XMLDOC.SelectNodes(XPath)
For i = 0 To nodelist.Length - 1
    Set Node = nodelist.NextNode
    Debug.Print Node.Text
Next i

我认为这是一个xml-treeing问题(我对XMLDom没有任何理解?)或xmlns / xsi问题,而且我完全陷入困境。

有人可以帮我吗?

1 个答案:

答案 0 :(得分:0)

必须为您要使用的每个命名空间选择一个名称空间前缀,即使XML中没有前缀。

在这里,我使用sub来引用http://www.xmlns.loc/sub命名空间。

Option Explicit

Sub Test()
    Dim XmlDoc As MSXML2.DOMDocument60
    Dim OnlyNodeType As MSXML2.IXMLDOMElement

    Set XmlDoc = GetXml("https://my.api.call.com/query?has_cheezburger")
    XmlDoc.setProperty "SelectionNamespaces", "xmlns:sub='http://www.xmlns.loc/sub'"

    For Each OnlyNodeType In XmlDoc.SelectNodes("//sub:OnlyNodeType")
        Debug.Print OnlyNodeType.GetAttribute("link")
    Next OnlyNodeType
End Sub

Function GetXml(url As String) As MSXML2.DOMDocument60
    With New MSXML2.XMLHTTP60
        .Open url
        .Send
        Set GetXml = .responseXML
        GetXml.setProperty "SelectionLanguage", "XPath"
    End With
End Function

XML具有默认命名空间的便利功能(没有显式前缀的命名空间声明,如xmlns="http://foo"而不是xmlns:foo="http://foo")。 XPath不存在这种便利设施。这里每个命名空间引用都必须是显式的。

只要命名空间URI匹配,您就可以选择任何您喜欢的前缀。