长期的读者,但在此先发帖。任何帮助都将受到高度赞赏!
我正在研究一个数据收集器,以从网格运算符获取我们客户的市场结果,并且需要一系列的xml查询。我能够使用SOAP模式(网格操作员要求)连接,认证并接收对我的查询的响应。但是,当我尝试使用LoadXML函数将从服务器接收到的xml字符串加载到DOMDocument60对象中时,它会从响应中剥离所有节点,并生成一个xml文档,其中只有一个节点中的标头,并串联一个存储在第二个节点中的字符串所有节点中的所有值。
因此,我无法提取所需的值。它们的长度各不相同,我无法知道一个值何时结束而下一个值开始。此外,由于已删除节点名称,因此当我尝试获取所有名为“ DSRSRREGAwardHourly”的节点的节点列表时,会得到一个空列表。
查询后从服务器收到的XML(为简化起见,我只留下了一个小时节点)
<?xml version='1.0' encoding='UTF-8'?>
<Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/">
<Body>
<QueryResponse xmlns="http://emkt.pjm.com/emkt/xml">
<DSRSRREGAwardSet>
<DSRSRREGAward day="2018-12-01" location="1960147390">
<DSRSRREGAwardHourly hour="1">
<SynchOfferMW>0.5</SynchOfferMW>
<RegOfferMW>0</RegOfferMW>
<SelfScheduledMW>0</SelfScheduledMW>
<SynchAwardedMW>0</SynchAwardedMW>
<RegAwardedMW>0</RegAwardedMW>
<RegOfferPriceUsed>0</RegOfferPriceUsed>
<RegdOfferMW>0</RegdOfferMW>
<RegdMW>0</RegdMW>
</DSRSRREGAwardHourly>
</DSRSRREGAward>
</DSRSRREGAwardSet>
</QueryResponse>
</Body>
</Envelope>
我正在使用的相关VBA代码
'Variable definition
Dim oWinhttp As WinHttpRequest
Dim ReturnXML As MSXML2.DOMDocument60
Dim ItemList As IXMLDOMNodeList
Dim XMLItem As IXMLDOMNode
'Variable initialization
Set oWinhttp = New WinHttpRequest
Set ReturnXML = New MSXML2.DOMDocument60
'Run the query against the server
With oWinhttp
Call .Open("POST", WebURL)
Call .SetRequestHeader("Cookie", "pjmauth=" & tokenStr)
Call .SetRequestHeader("Content-Type", "text/xml")
Call .SetRequestHeader("Content-Length", Len(xmlSubmittal))
Call .Send(xmlSubmittal)
Call .WaitForResponse
'Store the return XML into DOM Document
ReturnXML.async = False
ReturnXML.validateOnParse = False
ReturnXML.LoadXML (.ResponseText)
'Terminate connection
Call oWinhttp.abort
End With
'Extract nodes we are going to need
Set ItemList = ReturnXML.SelectNodes("//DSRSRREGAwardHourly")
答案 0 :(得分:0)
使用名称空间的简单XML解析
尝试以下代码行
[1]通过以下方式设置名称空间定义
ReturnXML.setProperty“ SelectionNamespaces”,xmlNameSpaces
其中xmlNameSpaces
只是一个字符串变量,用于复制xmlns
节点内的先前命名空间(<QueryResponse>
)属性。
相关代码段
XSLT
相关链接
C.f。 Obtain attribute names from XML using VBA
由于评论而产生的补遗
“我很好奇,这个问题是字符串定义了2个不同的名称空间,因此忽略了第二个吗?”
基本上是;层次结构中的后一个声明取代xml数据示例中的前一个声明(明确前缀的元素名称除外)。
' ...
'[1] Store the return XML into DOM Document using name spaces defining a leading "d:" prefix
ReturnXML.async = False
ReturnXML.validateOnParse = False
Dim xmlNameSpaces$
xmlNameSpaces = "xmlns:d=""http://emkt.pjm.com/emkt/xml""" ' define namespaces
ReturnXML.setProperty "SelectionNamespaces", xmlNameSpaces ' set namespace prop
ReturnXML.LoadXML (.ResponseText) ' get content
'[2] Loop through node lists (attention to the chosen namespace prefix)
Dim ItemList As MSXML2.IXMLDOMNodeList, ItemList2 As MSXML2.IXMLDOMNodeList
Dim item As MSXML2.IXMLDOMNode, item2 As MSXML2.IXMLDOMNode
Set ItemList = ReturnXML.SelectNodes("//d:DSRSRREGAwardHourly") ' <~~ leading "d:" :-)
For Each item In ItemList
Debug.Print "Day: " & item.SelectSingleNode("../@day").Text, _
"Hour: " & item.SelectSingleNode("./@hour").Text
Set ItemList2 = item.SelectNodes("d:*")
For Each item2 In ItemList2
Debug.Print vbTab & item2.nodeName, item2.Text
Next item2
Next item
(而不是可能基于的<SynchOfferMW>
在先前的名称空间声明<extra:SynchOfferMW>
中的其他显式前缀分配上)。对于无前缀的名称空间,您要声明两个默认名称空间,一个用于xmlns:extra="http://..."
元素,第二个用于<Envelope>
元素。<QueryResponse>
元素及其所有(未前缀)后代都属于第二个默认命名空间。