2013-09-03 2 views
0

Я пытаюсь разобрать ниже Xml. Это может иметь несколько тегов счета-фактуры:Анализ XML с использованием XmlDocument

<Invoices> 
    <Invoice> 
     <Invoice_ID>1234</Invoice_Id> 
     <Billing> 
      <Name> abc </Name> 
      <Address1>1 main street</Address1> 
      <City> city </city> 
      <State>State </State 
      <Zip>00000</zip> 
      <Amount> 
       <BaseAmt>35</BaseAmt> 
       <Tax>3</Tax> 
       <Total>28<total> 
      <Amount> 
     </Billing>  
     <item> 
       <Name> pen </Name> 
       <qty> 5 </qty> 
       <amount> 10 </amount> 
     </item> 
     <item> 
      <Name> Paper </Name> 
       <qty> 3 </qty> 
       <amount> 20 </amount> 
     </item>         
     </Invoice> 
</Invoices> 

Ниже мой код:

Dim xmlDoc As XmlDocument = New XmlDocument() 
xmlDoc.Load(fileName) 
Dim invNum As Integer = 0 
Dim nodeLst As XmlNodeList = xmlDoc.SelectNodes("/Invoices/Invoice") 
invNum = nodeLst.Count 

For Each invDetail As XmlElement In nodeLst 
    Dim invID As String = invDetail("Invoice_ID").InnerText.ToString() 
Next 

Мне нужно, чтобы получить значение для остальных тегов, то есть дочерние узлы, такие как Billing/Имя, Billing/Название/Сумма, Пункты/Items/имя

+0

Какая у вас проблема? –

+0

Я получил invID, используя invDetail («Invoice_ID») .InnerText, но когда я пытаюсь получить такое имя, как invDetail.SelectSingleNode («Billing/Name»), он дает мне ошибку: «Ссылка на объект не установлена ​​в экземпляр object " – user565992

+0

" Billing/Name "не является именем. Вам нужно' SelectSingleNode ("Billing") ', затем' SelectSingleNode ("Name") 'на этом. –

ответ

1

Если вы просто получить доступ к значению прямых дочернего элемента, как Invoice_ID, вы можете использовать индексацию, чтобы получить доступ дочернего элемента по имени, как вы уже делаете, как это:

invDetail("Invoice_ID") 

Однако, если вы хотите пойти глубже, чтобы получить значение нижнего потомка, вы можете использовать SelectSingleNode или SelectNodes для доступа к узлу с помощью XPath. XPath будет относиться к текущему узлу. Например:

For Each invDetail As XmlElement In nodeLst 
    Dim invID As String = invDetail("Invoice_ID").InnerText 
    Dim name As String = invDetail.SelectSingleNode("Billing/Name").InnerText 
    ' etc. 
    For Each item As XmlElement In invDetail.SelectNodes("item") 
     Dim itemName As String = item("Name").InnerText 
     ' etc. 
    Next 
Next 
+0

Я получил invID с помощью invDetail (" Invoice_ID ") .InnerText, но когда я пытаюсь получить такое имя, как invDetail.SelectSingleNode («Billing/Name»), он дает мне ошибку: «Ссылка на объект не установлена ​​на экземпляр объекта» – user565992

+0

Я только что протестировал его, и это работает для меня. Я обновил свой ответ, чтобы показать свой код. Должно быть что-то еще не так с вашим кодом или вашим XML. Если вы не можете понять это, пожалуйста, обновите свой вопрос с помощью фактического примера несоответствующего XML (текущий пример не является корректным, поэтому, очевидно, это не тот, который вы тестируете) и точный код, который не работает , –

+0

Спасибо Стивен Доггарт, я исправил эту ошибку и сделал ableto значение. Я не могу поставить фактические причины конфиденциальности Xml. Еще одна вещь, о которой мне нужна помощь, заключается в том, что в моем выше XMl вы видите тег элементов, как мне перебирать их, поскольку я уже в каждом цикле. – user565992

2

Две вещи нужно сделать, чтобы решить эту проблему:

1.) Ваш XML не очень хорошо сформирован. Помните, что XML чувствителен к регистру, требует закрытия скобок и т. Д .; в вашем XML-тексте есть многочисленные ошибки:

a. Откройте тег 'Invoice_ID' и закройте тег 'Invoice_Id' (должно быть <Invoice_ID> ... </Invoice_ID >).

b. Открыть тег «Город» и закрыть тег «город» (должно быть < Город > ... </Город >).

c. Элементу 'State' отсутствует прямоугольная скобка '>' на ее близком метке (должно быть </State >).

d. Открыть тег 'Zip' и закрыть тег 'zip' (должно быть < Почтовый индекс > ... </Почтовый индекс >).

e. Два открытых тега для «Сумма» (< Сумма > ... < Сумма >); должна быть открытая и закрытая бирка (< Сумма > ... </Сумма >).

f. Вам не хватает тега close для первого элемента item. (добавить </item >).

g. Открыть тег «Всего» и закрыть тег «всего» (должно быть < Всего > ... </Всего >).

Фиксированный на XML будет выглядеть следующим образом:

<Invoices> 
    <Invoice> 
     <Invoice_ID>1234</Invoice_ID> 
     <Billing> 
      <Name> abc </Name> 
      <Address1>1 main street</Address1> 
      <City> city </City> 
      <State>State </State> 
      <Zip>00000</Zip> 
      <Amount> 
       <BaseAmt>35</BaseAmt> 
       <Tax>3</Tax> 
       <Total>28</Total> 
      </Amount> 
     </Billing>  
     <Items> 
      <item> 
       <Name> pen </Name> 
       <qty> 5 </qty> 
       <amount> 10 </amount> 
      </item> 
      <item> 
       <Name> Paper </Name> 
       <qty> 3 </qty> 
       <amount> 20 </amount> 
      </item>           
     </Items> 
    </Invoice> 
</Invoices> 

2.) После того, как вы установили свой XML-код, чтобы выбрать все элементы «Счет-фактура» и получить доступ к их дочерним элементам (например, «Имя» и т. Д.), Вы можете сначала выбрать все элементы «Счет-фактура», а затем выполнить итерацию по каждому из них, дочерний элемент InnertText/значения, которые вам понадобятся.

XmlNodeList nodeList = doc.SelectNodes("//Invoice"); 

foreach (XmlNode invoice in nodeList) 
    Console.WriteLine(invoice.SelectSingleNode("Billing/Name").InnerText); 

Вывод из вышеизложенных будет гласить:

abc 

Надеется, что это помогает.