2013-05-22 42 views
1

我有一个XML文件通过VBA在Access 2010中通过WSDL检索。 XML文件是坐在这个变量从XML文件返回所有节点,即使它们为空

Dim xmlDoc As New DOMDocument60 

的XML我很感兴趣,貌似下方,基本上只是重申自己对每个UserBean的一部分。 A 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> 

的问题是,并非每一个字段是强制性的要填写。
因此,一些节点没有数据
使用MSXML2库中,如果确实有它的文本VBA只返回节点。 因此,下面的代码将根据每个userbean包含的内容返回可变数量的节点。例如,某些用户没有填充移动号码。

Set nodes xmlDoc.selectNodes("//UserBean") 
For Each node in nodes 
    debug.print node.text 
next node 

上面的代码返回了所有所有的子节点的值中有一个很长的字符串(关于Userbean节点),而只是说有文字的人。我试图把它放到Access的表格中,如果有些节点缺少一些时间,我没有办法跟踪它...或者我呢?

如何退还他们是否填充所有节点或不
OR
如何识别具有文本节点的名称,所以我知道放在哪里值到表中的访问?

UPDATE
继下面的评论,我后是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 
+0

可能:'debug.print node.nodename& “=” &node.text' –

+0

这已经很接近@Tim威廉姆斯。你的代码的结果是'UserBean = 4908414false614203Andrew .... etc',所以这些字段不会被破坏。UserBean实际上是一个节点列表,但在这里它被当作一个节点。 – zoonosis

+0

如果可能的话,启动一个SQL服务器引擎 - 它具有比Access更好的XML容量。 FWIW。 – DougM

回答

2

我后是Userbeans的列表,这是在自己的列表

你需要考虑的“节点”,而不是术语“名单。” selectNodes返回一个指向一组节点的指针,但是当你遍历它时,你会得到一个IXMLDOMNode而不是节点列表。你只能通过调用一个方法来获得nodeList,比如selectNodes。

你可以调用的selectNodes 再次,或者仅使用IXMLDOMNode的childNodes财产,Documented at 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 

注意用适当的XPath查询,你可以选择符合条件的节点列表。既然这是VBA,除非你想利用intellisense,否则你可以跳过显式声明。

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 
+1

试图编辑您的帖子为'badNode.name'应该是'badNode.nodeName',但它少于执行编辑所需的字符数量。 – zoonosis

+0

我尝试了两条建议,两者都很好。非常感谢,我从两种方法中学到了很多东西。一旦我将数据存入表格,我会发布我的最终解决方案供所有人共享。再次感谢。 – zoonosis