Excel VBA从XML获取特定节点

我从一个URL API(我没有共享的URL,因为它允许访问安全信息)的XML文件。 从这个文件我想获得一定的信息。 我的问题是,一旦我在父节点(eventNode),我想简单地能够从特定的子节点获取数据。

例如,如果eventNode是<event><ID>1</ID>...<title>event 1</title></event> ,那么我怎样才能知道节点名称是ID (或任何其他价值我想拉出)?

我已经看了很多通过论坛和.SelectSingleNode给了我没有运气。 此外.selectNodes不会像XMLstring中的正常节点列表一样工作。 我不知道这是否是由于我用来parsing我的XML文件的方法。

 Sub ListEvents() Dim strPath As String strPath = getAPI("GetEvents", "filter=&orderBy=") Dim xmlDocument As MSXML2.DOMDocument60 Set xmlDocument = New DOMDocument60 With CreateObject("MSXML2.XMLHTTP") .Open "GET", strPath, False .send xmlDocument.LoadXML .responseText End With Dim lvl1 As IXMLDOMNode: Dim lvl2 As IXMLDOMNode Dim eventNode As IXMLDOMNode: Dim isNode As IXMLDOMNode For Each lvl1 In xmlDocument.ChildNodes For Each lvl2 In lvl1.ChildNodes For Each eventNode In lvl2.ChildNodes If eventNode.HasChildNodes Then 'Here is where I want code to find specific child node 'without having to look at every node. End If Next Next Next End Sub 

示例XML:

 <?xml version="1.0" encoding="utf-8" ?> <ResultsOfListOfEvent xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://www.regonline.com/api"> <Success>true</Success> <Data> <APIEvent> <ID>111</ID> <CustomerID>222</CustomerID> <ParentID>0</ParentID> <Status>Testing</Status> <Title>Event Name</Title> <ClientEventID /> <TypeID>9</TypeID> <TimeZone>GMT</TimeZone> <CurrencyCode>GBP</CurrencyCode> <AddDate>2013-12-18T02:34:09.357</AddDate> <Channel>Running</Channel> <IsWaitlisted>false</IsWaitlisted> </APIEvent> <APIEvent> <ID>112</ID> <CustomerID>223</CustomerID> <ParentID>0</ParentID> <Status>Testing</Status> <Title>Event Name</Title> <ClientEventID /> <TypeID>9</TypeID> <TimeZone>GMT</TimeZone> <CurrencyCode>GBP</CurrencyCode> <AddDate>2013-12-18T02:34:09.357</AddDate> <Channel>Running</Channel> <IsWaitlisted>false</IsWaitlisted> </APIEvent> </Data> </ResultsOfListOfEvent> 

我想在每个<ID> (即111112 )和每个<Title>输出文本。 这只是一个例子,取决于我运行的API,我将希望能够select我所提供的信息。

试试这个 – 你可以修改下面的代码来获取任何子节点

 Set xmlDoc = CreateObject("Microsoft.XMLDOM") xmlDoc.SetProperty "SelectionLanguage", "XPath" xmlDoc.Async = False xmlDoc.Load("C:\Users\pankaj.jaju\Desktop\Test.xml") Set nodeXML = xmlDoc.getElementsByTagName("ID") For i = 0 To nodeXML.Length - 1 MsgBox nodeXML(i).Text Next 

从问题作者编辑:

这很好。 对于任何读者,这是我如何使用上面的答案来适应我的代码(因为我从URL加载XML – 而不是文件):

 Sub ListEvents() Dim myURL As String myURL = getAPI("GetEvents", "filter=&orderBy=") Set xmlDoc = CreateObject("Microsoft.XMLDOM") xmlDoc.setProperty "SelectionLanguage", "XPath" xmlDoc.async = False With CreateObject("MSXML2.XMLHTTP") .Open "GET", myURL, False .send xmlDoc.LoadXML .responseText End With Set nodeXML = xmlDoc.getElementsByTagName("ID") For i = 0 To nodeXML.Length - 1 MsgBox nodeXML(i).Text Next End Sub 

上面的Pankaj Jaju的回答是一个稍微不同的方法。

笔记:

  • 使用MSXML2名称空间作为旧的Microsoft.XMLDOM一个只保留为遗留支持 – 请参阅此处
  • 使用“SelectionNamespaces”属性来解决当文档具有默认名称空间时MSXML2与XPath所具有的问题 – 请参阅此处 。 我们创build一个名为r的名称空间(任何名字都可以),它具有与文档中默认名称空间相同的URI引用(本例中为http://www.regonline.com/api
  • 在XPath中使用这个新的名称空间作为任何具有前缀名的元素的前缀。 这是一种复杂的说法,而不是寻找/ID ,我们会寻找/r:ID

这里是代码:

 Sub foo() Dim xmlDoc As Object Dim xmlNodeList As Object Dim xmlNode As Object Set xmlDoc = CreateObject("MSXML2.DOMDocument.6.0") xmlDoc.setProperty "SelectionNamespaces", "xmlns:r='http://www.regonline.com/api'" xmlDoc.async = False xmlDoc.Load "C:\Users\colin\Desktop\yoz1234.xml" Set xmlNodeList = xmlDoc.selectNodes("/r:ResultsOfListOfEvent/r:Data/r:APIEvent/r:ID") For Each xmlNode In xmlNodeList MsgBox xmlNode.Text Next xmlNode End Sub