Excel VBA从XML获取特定节点
我有一个来自URL API的XML文件(这个URL我没有共享,因为它允许访问安全信息)。我想从这个文件中得到一些信息。我的问题是,一旦我在父节点(eventNode)中,我只希望能够从特定的子节点获取数据 例如,如果eventNode是Excel VBA从XML获取特定节点,xml,excel,vba,ixmldomnode,Xml,Excel,Vba,Ixmldomnode,我有一个来自URL API的XML文件(这个URL我没有共享,因为它允许访问安全信息)。我想从这个文件中得到一些信息。我的问题是,一旦我在父节点(eventNode)中,我只希望能够从特定的子节点获取数据 例如,如果eventNode是1…event 1,那么仅知道节点名是ID(或我想提取的任何其他值),我将如何获得1 我在论坛上浏览了很多次,.SelectSingleNode没有给我带来好运。另外,.selectNodes的作用与XML字符串中的普通节点列表不同。我不知道这是否是由于我用来解析
1…event 1
,那么仅知道节点名是ID
(或我想提取的任何其他值),我将如何获得1
我在论坛上浏览了很多次,.SelectSingleNode
没有给我带来好运。另外,.selectNodes
的作用与XML字符串中的普通节点列表不同。我不知道这是否是由于我用来解析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>
真的
111
222
0
测试
事件名称
9
格林尼治标准时间
英镑
2013-12-18T02:34:09.357
跑步
假的
112
223
0
测试
事件名称
9
格林尼治标准时间
英镑
2013-12-18T02:34:09.357
跑步
假的
我想在每个
(即111
和112
)和每个
中输出文本。这只是一个示例,根据我运行的API,我希望能够拾取和选择我提取的信息。试试这个-您可以修改下面的代码来获取任何子节点
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,而不是从文件加载):
这里有一个稍微不同的方法,它建立在上面Pankaj Jaju的答案之上 注:
- 使用MSXML2命名空间,因为旧的Microsoft.XMLDOM命名空间仅为旧版支持而维护—请参阅
- 使用“SelectionNamespaces”属性修复当文档具有默认命名空间时MSXML2与XPath之间存在的问题-请参阅。我们创建一个名为
(任何名称都可以)的名称空间,该名称空间与文档中的默认名称空间具有相同的URI引用(r
在这种情况下)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
发布示例xml和预期输出请同时发布您预期的示例输出。。。正如您希望获取的子节点一样,我希望在每个节点(即111和112)和每个节点中输出文本。这只是一个例子,根据我运行的API,我希望能够选择我提取的信息?我需要能够说给定的x个子节点返回文本,而不必查看每个节点。例如,某种类型的getNodeText(“ID”)+1@user1559727,用于丰富答案以满足您和其他用户的需要。对不起,在答案的第二部分中,我们在哪里输入URL?
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