VB.NET读取XML文件的麻烦

时间:2011-04-12 19:26:15

标签: xml vb.net xml-parsing xmlreader

我使用以下代码来解析我的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.dll中发生'System.Xml.XmlException'类型的第一次机会异常

System.Xml.dll中出现'System.Xml.XmlException'类型的第一次机会异常 ':'字符,十六进制值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 个答案:

答案 0 :(得分:1)

1.试试这个,

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

2.采用传统循环方法的另一种解决方案,

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

在类顶部导入命名空间。而不是使用follwoing代码来获取值,

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

答案 1 :(得分:1)

在代码顶部的任何类/名称空间声明上方导入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()

编辑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

编辑3

嗯,你只给了我一部分XML;)所以我不得不做一些。这里的诀窍是getXMLData将是XElement,特别是<csr:custom_attribute>节点。有了它,您需要返回原始代码并使用Select New...代码。

为方便起见,我将您的XML字符串转换为原始XDocument,因为所有的concats都让它难以阅读。 请记住,我的XML可能与您的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