Проблемы с чтением XML-файлов в VB.NET - PullRequest
1 голос
/ 12 апреля 2011

Я использую следующий код для анализа моего XML-файла:

Dim xml As String = "<?xml version=""1.0"" encoding=""Windows-1252""?>" & _
                        "<theref:theref-msg xmlns:csr=""http://www.xxxxx.com/Schema/csr"" xmlns:theref=""http://www.xxxxx.com/Schema/theref"">" & _
                          "<theref:header>" & _
                            "<theref:eid />" & _
                            "<theref:reference_id>429</theref:reference_id>" & _
                            "<theref:sr_type_code>US1</theref:sr_type_code>" & _
                            "<theref:event_type_code>REQUEST</theref:event_type_code>" & _
                            "<theref:eai_event_code>DSR</theref:eai_event_code>" & _
                            "<theref:source_code>WORKS</theref:source_code>" & _
                            "<theref:target_code>APP</theref:target_code>" & _
                            "<theref:status_code />" & _
                            "<theref:details />" & _
                          "</theref:header>" & _
                        "</theref:theref-msg>"

    Dim document As XDocument = XDocument.Parse(xml)

    Dim pupils = From pupil In document.Descendants("theref:theref-msg") _
                 Select New With _
                 { _
                    .Name = pupil.Element("theref:reference_id").Value, _
                    .TagID = pupil.Element("theref:sr_type_code").Value _
                 }

    For Each pupil In pupils
        Debug.Print("{0}: {1}", pupil.Name, pupil.TagID)
    Next

Проблема в том, что он не работает вообще.Сбой в строке:

Dim pupils = From pupil In document.Descendants("csreai:csreai-msg") _
                 Select New With _
                 { _
                    .Name = pupil.Element("csreai:reference_id").Value, _
                    .TagID = pupil.Element("csreai:sr_type_code").Value _
                 }

ОШИБКА: Произошло первое исключение типа System.Xml.XmlException в System.Xml.dll

Первое случайное исключение типа «System.Xml.XmlException» произошло в System.Xml.dll. Символ «:», шестнадцатеричное значение 0x3A, нельзя включить в имя.5

ОБНОВЛЕННЫЙ КОД:

Dim xml As String = "<?xml version=""1.0"" encoding=""Windows-1252""?>" & _
                    "<theref:theref-msg xmlns:csr=""http://www.xxxxx.com/Schema/csr"" xmlns:theref=""http://www.xxxxx.com/Schema/theref"">" & _
                      "<theref:header>" & _
                        "<theref:eid />" & _
                        "<theref:reference_id>429</theref:reference_id>" & _
                        "<theref:sr_type_code>US1</theref:sr_type_code>" & _
                        "<theref:event_type_code>REQUEST</theref:event_type_code>" & _
                        "<theref:eai_event_code>DSR</theref:eai_event_code>" & _
                        "<theref:source_code>WORKS</theref:source_code>" & _
                        "<theref:target_code>APP</theref:target_code>" & _
                        "<theref:status_code />" & _
                        "<theref:details />" & _
                      "</theref:header>" & _
                      "<theref:body>" & _
                        "<csr:document>" & _
                          "<csr:header>" & _
                            "<csr:system>CSR</csr:system>" & _
                            "<csr:doc_name>FULLSR</csr:doc_name>" & _
                            "<csr:version>3.1</csr:version>" & _
                            "<csr:dml_event>UPDATE</csr:dml_event>" & _
                          "</csr:header>" & _
                    "</csr:document></theref:body></theref:theref-msg>"

Dim xmlb = From getXMLData In document.<theref:theref-msg>.<theref:header>.<theref:body>.<csr:document>.<csr:header>

Новейшее ОБНОВЛЕНИЕ

Что если у меня есть это:

   <csr:custom_attributes>
      <csr:custom_attribute>
        <csr:type_code>
          <csr:value>data1</csr:value>
        </csr:type_code>
        <csr:group_code>
          <csr:value>wide1</csr:value>
        </csr:group_code>
      </csr:custom_attribute>
      <csr:custom_attribute>
        <csr:type_code>
          <csr:value>data2</csr:value>
        </csr:type_code>
        <csr:group_code>
          <csr:value>wide2</csr:value>
        </csr:group_code>
      </csr:custom_attribute>
   </csr:custom_attributes>

Кажется, я могу получить только первый набор данных ( data1, wide1 ), но не второй?

   xmlDATA = (From getXMLData In document.<theref:csreai-msg>.<theref:body>.<csr:document>.<csr:service_request>.<csr:custom_attributes>.<csr:custom_attribute>).ToList()

Ответы [ 2 ]

1 голос
/ 13 апреля 2011

В верхней части кода над объявлениями любого класса / пространства имен импортируйте пространство имен theref:

Imports <xmlns:theref="http://www.xxxxx.com/Schema/theref">

Затем вы можете просто использовать литералы XML для выбора с помощью

Option Explicit On
Option Strict On

Imports <xmlns:theref="http://www.xxxxx.com/Schema/theref">

Public Class Form1

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Dim xml As String = "<?xml version=""1.0"" encoding=""Windows-1252""?>" & _
                        "<theref:theref-msg xmlns:csr=""http://www.xxxxx.com/Schema/csr"" xmlns:theref=""http://www.xxxxx.com/Schema/theref"">" & _
                          "<theref:header>" & _
                            "<theref:eid />" & _
                            "<theref:reference_id>429</theref:reference_id>" & _
                            "<theref:sr_type_code>US1</theref:sr_type_code>" & _
                            "<theref:event_type_code>REQUEST</theref:event_type_code>" & _
                            "<theref:eai_event_code>DSR</theref:eai_event_code>" & _
                            "<theref:source_code>WORKS</theref:source_code>" & _
                            "<theref:target_code>APP</theref:target_code>" & _
                            "<theref:status_code />" & _
                            "<theref:details />" & _
                          "</theref:header>" & _
                        "</theref:theref-msg>"

        Dim document As XDocument = XDocument.Parse(xml)

        Dim pupils = From pupil In document.<theref:theref-msg>.<theref:header>
                     Select New With
                            {
                                .Name = pupil.<theref:reference_id>.Value,
                                .TagID = pupil.<theref:sr_type_code>.Value
                            }


        Dim pupilList = pupils.ToList()

        For Each pupil In pupilList
            Debug.Print("{0}: {1}", pupil.Name, pupil.TagID)
        Next
    End Sub
End Class

РЕДАКТИРОВАТЬ

Вам необходимо Import каждое пространство имен, которое вы хотите использовать в литерале XML.Таким образом, ваш импорт теперь должен быть:

Imports <xmlns:theref="http://www.xxxxx.com/Schema/theref">
Imports <xmlns:csr="http://www.xxxxx.com/Schema/csr">

Это устранит ошибки компиляции.Затем вам также необходимо удалить <theref:header> из запроса, поскольку <theref:body> является родственным для него, а не дочерним.При отладке подобных вещей я также рекомендую всегда с использованием ToList().Когда вы приступили к работе, вы можете удалить это по соображениям производительности (я обычно не беспокоюсь).

Dim xmlb = (From getXMLData In document.<theref:theref-msg>.<theref:body>.<csr:document>.<csr:header>).ToList()

EDIT 2

Вот полный код, используя вашновые данные XML.Когда я запускаю его, я получаю сообщение «CSR»

Option Explicit On
Option Strict On

Imports <xmlns:theref="http://www.xxxxx.com/Schema/theref">
Imports <xmlns:csr="http://www.xxxxx.com/Schema/csr">

Public Class Form1

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Dim xml As String = "<?xml version=""1.0"" encoding=""Windows-1252""?>" & _
                     "<theref:theref-msg xmlns:csr=""http://www.xxxxx.com/Schema/csr"" xmlns:theref=""http://www.xxxxx.com/Schema/theref"">" & _
                       "<theref:header>" & _
                         "<theref:eid />" & _
                         "<theref:reference_id>429</theref:reference_id>" & _
                         "<theref:sr_type_code>US1</theref:sr_type_code>" & _
                         "<theref:event_type_code>REQUEST</theref:event_type_code>" & _
                         "<theref:eai_event_code>DSR</theref:eai_event_code>" & _
                         "<theref:source_code>WORKS</theref:source_code>" & _
                         "<theref:target_code>APP</theref:target_code>" & _
                         "<theref:status_code />" & _
                         "<theref:details />" & _
                       "</theref:header>" & _
                       "<theref:body>" & _
                         "<csr:document>" & _
                           "<csr:header>" & _
                             "<csr:system>CSR</csr:system>" & _
                             "<csr:doc_name>FULLSR</csr:doc_name>" & _
                             "<csr:version>3.1</csr:version>" & _
                             "<csr:dml_event>UPDATE</csr:dml_event>" & _
                           "</csr:header>" & _
                     "</csr:document></theref:body></theref:theref-msg>"

        Dim document As XDocument = XDocument.Parse(xml)

        Dim xmlb = (From getXMLData In document.<theref:theref-msg>.<theref:body>.<csr:document>.<csr:header>).ToList()
        MsgBox(xmlb.<csr:system>.Value)

    End Sub
End Class

EDIT 3

Ну, вы дали мне только часть своего XML;), поэтому япришлось сделать некоторые из этого.Хитрость в том, что getXMLData будет XElement, а именно <csr:custom_attribute> узлом.После этого вам нужно вернуться к исходному коду и использовать код Select New....

Для удобства я преобразовал вашу XML-строку в необработанный XDocument, потому что все конкататы затрудняли его чтение. Помните , мой XML может не совпадать с вашим, потому что вы дали мне только часть.

Option Explicit On
Option Strict On

Imports <xmlns:theref="http://www.xxxxx.com/Schema/theref">
Imports <xmlns:csr="http://www.xxxxx.com/Schema/csr">

Public Class Form1
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Dim document = <?xml version="1.0" encoding="Windows-1252"?>
                       <theref:theref-msg xmlns:csr="http://www.xxxxx.com/Schema/csr" xmlns:theref="http://www.xxxxx.com/Schema/theref">
                           <theref:body>
                               <csr:document>
                                   <csr:service_request>
                                       <csr:custom_attributes>
                                           <csr:custom_attribute>
                                               <csr:type_code>
                                                   <csr:value>data1</csr:value>
                                               </csr:type_code>
                                               <csr:group_code>
                                                   <csr:value>wide1</csr:value>
                                               </csr:group_code>
                                           </csr:custom_attribute>
                                           <csr:custom_attribute>
                                               <csr:type_code>
                                                   <csr:value>data2</csr:value>
                                               </csr:type_code>
                                               <csr:group_code>
                                                   <csr:value>wide2</csr:value>
                                               </csr:group_code>
                                           </csr:custom_attribute>
                                       </csr:custom_attributes>
                                   </csr:service_request>
                               </csr:document>
                           </theref:body>
                       </theref:theref-msg>

        Dim xmlDATA = (
                        From getXMLData In document.<theref:theref-msg>.<theref:body>.<csr:document>.<csr:service_request>.<csr:custom_attributes>.<csr:custom_attribute>
                        Select New With {.TypeCode = getXMLData.<csr:type_code>.<csr:value>.Value, .GroupCode = getXMLData.<csr:group_code>.<csr:value>.Value}
                      ).ToList()
        For Each X In xmlDATA
            Trace.WriteLine(X.TypeCode & ":" & X.GroupCode)
        Next
    End Sub
End Class
1 голос
/ 13 апреля 2011

1. Попробуйте с этим,

       document.Descendants("{http://www.xxxxx.com/Schema/theref}theref-msg").FirstOrDefault

2. Другое решение с традиционным циклическим подходом,

     Imports <xmlns:ns='http://www.xxxxx.com/Schema/theref'> 

импортировать пространство имен поверх класса. чем использовать следующий код для получения значений,

         For Each header As XElement In document.<ns:theref-msg>.<ns:header>.<ns:reference_id>
             dim something = header.Value
         Next
...