简体   繁体   English

从XML文件返回所有节点,即使它们为空

[英]Return all nodes from XML file, even when they are empty

I have an XML file retrieved via WSDL in Access 2010 via VBA. 我有一个通过VBA在Access 2010中通过WSDL检索的XML文件。 The XML file is sitting in this variable 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 . 我感兴趣的XML部分如下所示,基本上只是为每个UserBean重申了一下。 A UserBean is basically a user account in a system. UserBean基本上是系统中的用户帐户。

<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. 如果VBA中确实包含文本,则在VBA中使用MSXML2库只会返回节点。 Therefore the code below will return a variable amount of nodes depending on what each userbean contains. 因此,以下代码将根据每个userbean包含的内容返回可变数量的节点。 For example some users dont have a mobileNumber populated. 例如,某些用户没有填充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. 上面的代码返回一个长字符串,其中包含所有子节点(相对于Userbean节点)的所有值,但仅包含文本的值。 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? 我试图将其放入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? 如何确定具有文本的节点的名称,以便知道在Access中将值放入表中的位置?

UPDATE 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. 除了下面的评论外,我所关注的是Userbeans列表,它们本身就是一个列表...所以实际上我在列表列表之后...因此我考虑了以下内容,但是它在第一个For Each循环中失败。 Obviously that type of loop can't handle using lists as a counter for another list. 显然,这种循环类型无法使用列表作为另一个列表的计数器。 Is there a way around this? 有没有解决的办法?

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

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. selectNodes返回一个指向一组节点的指针,但是当您对其进行迭代时,您将看到一个IXMLDOMNode而不是Node List。 You can only get a nodeList by calling a method, such as selectNodes. 您只能通过调用方法(例如selectNodes)来获取nodeList。

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. 请注意,使用适当的XPath查询,您只需选择符合条件的节点列表即可。 And since this is VBA, you can skip the explicit declarations unless you're going to take advantage of the intellisense. 由于这是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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM