2013-05-22 2 views
1

У меня есть XML-файл, полученный через WSDL в Access 2010 через VBA. Файл 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 только возвращает узлы, если есть на самом деле текст в нем. Поэтому приведенный ниже код вернет переменное количество узлов в зависимости от того, что содержит каждый пользователь. Например, некоторые пользователи не имеют заполненного мобильного номера.

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

Приведенный выше код возвращает длинную строку, которая имеет все значения всех дочерних узлов в нем (по отношению к Userbean узла), но только те, которые имеют текст. Я пытаюсь получить это в таблице в Access, и если некоторые из узлов будут отсутствовать некоторое время, у меня нет способа отслеживать это ... или я?

Как вернуть все узлы, являются ли они или не заселенными
ИЛИ
Как определить имя узла, который имеет текст, так что я знаю, куда поместить значение в таблицу в Access?

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

Это близко @ Тим Уильямс. Результатом вашего кода является «UserBean = 4908414false614203Andrew .... etc», поэтому поля не будут разбиты.«UserBean» - это действительно список узлов, но здесь он рассматривается как один узел. – zoonosis

+0

Если это вообще возможно, разверните механизм SQL-сервера - у него есть более быстрые возможности XML, чем Access. FWIW. – DougM

ответ

2

, что я после того, как список Userbeans, которые сами по себе список

Вы должны думать в терминах «узлов», а не «списки.» selectNodes возвращает указатель на набор узлов, но когда вы перебираете его, вы завершаете IXMLDOMNode, а не список узлов. Вы можете получить только nodeList, вызвав метод, например selectNodes.

Вы можете позвонить SelectNodes снова, или просто использовать childNodes свойство IXMLDOMNode, в 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 Query, вы можете просто выбрать список узлов, которые отвечают вашим критериям. И поскольку это 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