vba 从 XML 文件返回所有节点,即使它们是空的
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/16685190/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Return all nodes from XML file, even when they are empty
提问by zoonosis
I have an XML file retrieved via WSDL in Access 2010 via VBA. The XML file is sitting in this variable
我通过 VBA 在 Access 2010 中通过 WSDL 检索了一个 XML 文件。XML 文件位于此变量中
Dim xmlDoc As New DOMDocument60
The part of the XML I'm interested in looks like the below and basically just reiterates itself for every UserBean
. A UserBean
is basically a user account in a system.
我感兴趣的 XML 部分如下所示,基本上只是为每个UserBean
. AUserBean
基本上是系统中的用户帐户。
<UserBean xsi:type="ns1:UserBean">
<primaryKey xsi:type="xsd:string">49084</primaryKey>
<updateIndex xsi:type="xsd:int">14</updateIndex>
<deleted xsi:type="xsd:boolean">false</deleted>
<loginID xsi:type="xsd:string">61420313556</loginID>
<name xsi:type="xsd:string">Andrew Mills</name>
<teams xsi:type="soapenc:Array" soapenc:arrayType="xsd:string[1]">
<string xsi:type="xsd:string">Maintenance</string>
</teams>
<timezone xsi:type="xsd:string">Australia/Brisbane</timezone>
<userTypePK xsi:type="xsd:string">3776</userTypePK>
<description xsi:type="xsd:string"/>
<emailAddress xsi:type="xsd:string"/>
<phoneNumber xsi:type="xsd:string"/>
<faxNumber xsi:type="xsd:string"/>
<pagerNumber xsi:type="xsd:string"/>
<mobileNumber xsi:type="xsd:string">61420313556</mobileNumber>
<securityQuestion xsi:type="xsd:string">__INVALID</securityQuestion>
<securityAnswer xsi:type="xsd:string"/>
<synchronisation xsi:type="soapenc:Array" soapenc:arrayType="ns2:SynchronisationBean[0]" xmlns:ns2="http://soap2.nads.econz.co.nz"/>
</UserBean>
The problem is that not every field is mandatory to be filled in.
Therefore some nodes have no data
Using the MSXML2 library in VBA only returns nodes if there is actually text in it.
Therefore the code below will return a variable amount of nodes depending on what each userbean contains. For example some users dont have a mobileNumber populated.
问题是并非每个字段都必须填写。
因此,某些节点没有数据
在 VBA 中使用 MSXML2 库仅返回节点,如果其中确实有文本。因此,下面的代码将根据每个 userbean 包含的内容返回可变数量的节点。例如,某些用户没有填充 mobileNumber。
Set nodes xmlDoc.selectNodes("//UserBean")
For Each node in nodes
debug.print node.text
next node
The above code returns a long string that has all of the values of all of the child nodes in it (with respect to the Userbean
node), but only the ones that have text. I'm trying to get this into a table in Access and if some of the nodes are missing some of the time, I've got no way of tracking it... or do I?
上面的代码返回一个长字符串,其中包含所有子节点的所有值(相对于Userbean
节点),但只有那些具有文本的值。我正在尝试将其放入 Access 中的表中,如果某些节点有时丢失,我将无法跟踪它......或者是吗?
How do I return ALL nodes whether they are populated or not
OR
How do I identify the name of the node that has the text so I know where to put the value into the table in Access?
如何将所有节点返回它们是否被填充与否
或
如何识别具有文本节点的名称,所以我知道放在哪里值到表中的访问?
UPDATE
Further to the below comments, what i'm after is a list of Userbeans, which are in themselves a list...so in fact i'm after a list of lists...so with that in mind I tried the below but it failed at the first For Each
loop. Obviously that type of loop can't handle using lists as a counter for another list. Is there a way around this?
更新
除了下面的评论之外,我所追求的是一个 Userbeans 列表,它们本身就是一个列表......所以实际上我在一个列表列表之后......所以考虑到这一点,我尝试了以下但它在第一个For Each
循环中失败了。显然,这种类型的循环无法处理使用列表作为另一个列表的计数器。有没有解决的办法?
Dim node As MSXML2.IXMLDOMNode
Dim userbeans As MSXML2.IXMLDOMNodeList
Dim userbean As MSXML2.IXMLDOMNodeList
Set userbeans = xmlDoc.selectNodes("//UserBean")
For Each userbean In userbeans '**Type mismatch error here**
For Each node In userbean
Debug.Print node.nodeName & ":" & node.Text
Next node
Next userbean
回答by DougM
what i'm after is a list of Userbeans, which are in themselves a list
我想要的是一个 Userbeans 列表,它们本身就是一个列表
You need to think in terms of "nodes", not "lists." selectNodes
returns a pointer to a set of nodes, but when you iterate through it you wind up with an IXMLDOMNode, not a Node List. You can only get a nodeList by calling a method, such as selectNodes.
您需要考虑“节点”,而不是“列表”。 selectNodes
返回一个指向一组节点的指针,但是当你遍历它时,你会得到一个 IXMLDOMNode,而不是一个节点列表。只能通过调用方法获取一个nodeList,比如selectNodes。
You can to call selectNodes again, or just use the IXMLDOMNode's childNodes
property, Documented at MSDN
您可以再次调用 selectNodes ,或者只使用 IXMLDOMNode 的 childNodes
属性,文档在 MSDN
Dim userBeanList As MSXML2.IXMLDOMNodeList
Dim userbean As MSXML2.IXMLDOMNode
Dim beanChild As MSXML2.IXMLDOMNode
Set userBeanList = xmlDoc.selectNodes("//UserBean")
For Each userBean In userBeanList
For Each beanChild In userBean.childNodes
Debug.Print beanChild.nodeName & ":" & beanChildText
Next beanChild
Next userBean
Note that with a proper XPath Query, you can just select a list of nodes that meet your criteria. And since this is VBA, you can skip the explicit declarations unless you're going to take advantage of the intellisense.
请注意,使用适当的 XPath 查询,您只需选择符合条件的节点列表。由于这是 VBA,您可以跳过显式声明,除非您打算利用智能感知。
dim badNodes, badNode
set badNodes = xmlDoc.selectNodes("//UserBean/*[not(text())]")
if badNodes.length < 1 then
debug.Print "All good!"
else
debug.Print "following nodes are empty:"
For Each badNode in badNodes
debug.print " - " & badNode.name
next badNode
endif