【问题标题】:VB.NET reading XML file troublesVB.NET读取XML文件的烦恼
【发布时间】:2011-04-12 19:26:15
【问题描述】:

我正在使用以下代码来解析我的 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()

【问题讨论】:

  • VB.NET 具有内联 XML 常量。为什么使用String
  • 另外,“它崩溃了”是什么意思?请发布例外情况。
  • 也可以查看&lt;/&lt;theref:theref-msg&gt;。那是坏了。此外,此时包含encoding 声明毫无意义。
  • @John 他希望能够从文件中读取它,并且仅将字符串显示为示例
  • @Yet:他应该使用 XML Literal 作为示例,并且他会立即收到来自 VB.NET 的错误,显示他的错字。字符串几乎不应该用于 XML。

标签: xml vb.net xml-parsing xmlreader


【解决方案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">

这将清除编译错误。接下来,您还需要从查询中删除&lt;theref:header&gt;,因为&lt;theref:body&gt; 是它的兄弟而不是孩子。在调试这类事情时,我还建议始终使用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,特别是一个&lt;csr:custom_attribute&gt; 节点。有了它,您需要返回原始代码并使用 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

【讨论】:

  • 似乎没有找到任何东西。它跳过 Debug.Print("{0}: {1}", 瞳孔.Name, 瞳孔.TagID) 代码。
  • 您使用的是VB2010,对吗?如果您创建一个全新的 Windows 窗体应用程序,然后将上面的整个代码复制到 Form1.vb 的内容上,它应该会将 429: US1 踢到即时窗口。这不会发生吗?
  • 是的,我正在使用 VB2010。但是上面的代码似乎仍然不起作用。 pupilList 一直在说它的 0
  • @StealthRT,不幸的是我们又陷入了僵局。我刚刚测试了上面的代码(再一次,完全正确),它为我弹出了CSR
【解决方案2】:

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

【讨论】:

  • 当我使用 From 瞳孔 In document.Descendants("theref:theref-msg")
猜你喜欢
  • 1970-01-01
  • 2014-05-17
  • 1970-01-01
  • 2012-09-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多