2017-11-25 170 views
1

我想反序列化来自webrequest的XML字符串,我无法将其添加到自定义对象列表中,我可以遍历,我只花了2个小时左右这和我无法弄清楚我做错了什么,这是我第一次尝试类似的东西,所以在这一点上我有点无知。XML反序列化为自定义对象列表

因此,这里是我尝试反序列化的XML:

<?xml version="1.0" encoding="UTF-8"?> 
<school_search> 
    <summary> 
    <total_schools>5</total_schools> 
    <category>private</category> 
    </summary> 
    <schools> 
    <school> 
     <school_id>12</school_id> 
     <school_name>School of Literature</school_name> 
    </school> 
    <school> 
     <school_id>31</school_id> 
     <school_name>School of Sports</school_name> 
    </school> 
    <school> 
     <school_id>38</school_id> 
     <school_name>School of Arts</school_name> 
    </school> 
    <school> 
     <school_id>40</school_id> 
     <school_name>School of Science</school_name> 
    </school> 
    <school> 
     <school_id>43</school_id> 
     <school_name>School of Business</school_name> 
    </school> 
    </schools> 
</school_search> 

这是我创建处理这个特定的XML类:

<XmlRoot(ElementName:="school_search")> 
    Public Class xmlSchool_search 
     <XmlElement(ElementName:="summary")> 
     Public Property Summary() As xmlSummary 
      Get 
       Return m_Summary 
      End Get 
      Set 
       m_Summary = Value 
      End Set 
     End Property 
     Private m_Summary As xmlSummary 
     <XmlElement(ElementName:="schools")> 
     Public Property Schools() As xmlSchools 
      Get 
       Return m_Schools 
      End Get 
      Set 
       m_Schools = Value 
      End Set 
     End Property 
     Private m_Schools As xmlSchools 
    End Class 

    <XmlRoot(ElementName:="schools")> 
    Public Class xmlSchools 
     <XmlElement(ElementName:="school")> 
     Public Property School() As List(Of xmlSchool) 
      Get 
       Return m_School 
      End Get 
      Set 
       m_School = Value 
      End Set 
     End Property 
     Private m_School As List(Of xmlSchool) 
    End Class 

    <XmlRoot(ElementName:="summary")> 
    Public Class xmlSummary 
     <XmlElement(ElementName:="total_Schools")> 
     Public Property Total_schools() As String 
      Get 
       Return m_Total_schools 
      End Get 
      Set 
       m_Total_schools = Value 
      End Set 
     End Property 
     Private m_Total_schools As String 

     <XmlElement(ElementName:="category")> 
     Public Property Category() As String 
      Get 
       Return m_Category 
      End Get 
      Set 
       m_Category = Value 
      End Set 
     End Property 
     Private m_Category As String 

    End Class 

    <XmlRoot(ElementName:="school")> 
    Public Class xmlSchool 
     <XmlElement(ElementName:="school_id")> 
     Public Property School_id() As String 
      Get 
       Return m_School_id 
      End Get 
      Set 
       m_School_id = Value 
      End Set 
     End Property 
     Private m_School_id As String 

     <XmlElement(ElementName:="school_name")> 
     Public Property School_name() As String 
      Get 
       Return m_School_name 
      End Get 
      Set 
       m_School_name = Value 
      End Set 
     End Property 
     Private m_School_name As String 

    End Class 

这是将xml反序列化到我的自定义类中的相关代码:

request = DirectCast(WebRequest.Create(address), HttpWebRequest) 
    response = DirectCast(request.GetResponse(), HttpWebResponse) 

    Dim schoolsList As List(Of xmlSchool) 
    Using reader As New StreamReader(response.GetResponseStream()) 
     Dim deserializer As New XmlSerializer(GetType(List(Of xmlSchool)), New XmlRootAttribute("schools")) 
     schoolsList = DirectCast(deserializer.Deserialize(reader), List(Of xmlSchool)) 
    End Using 

最后这是我使用来遍历它:

For Each school As xmlSchool In schoolsList 
    HttpContext.Current.Response.Write(school.School_id) 
    HttpContext.Current.Response.Write("<br/>") 
Next 

问题: 我总是得到以下异常:

System.InvalidOperationException: There is an error in XML document (2, 2). ---> System.InvalidOperationException: <school_search xmlns=''> was not expected. 

我已经尝试将XmlRootAttribute更改为school_search,并且它没有抛出异常,但是schoolList是e mpty,我相信问题出现在自定义类中,但我不知道问题出在哪里。

非常感谢您提前花时间调查此问题。

+0

当发布任何东西包含XML,请注意并确保所有的XML都是代码格式(无论是反引号还是缩进4个空格)。如果你不这样做,你的标签将被默默丢弃并且不会出现在渲染的问题中。我修复了异常消息。 –

+0

我很抱歉,吉姆,谢谢你的编辑! –

+0

学习过程的所有部分,不幸的是,它并不是马上明白SO降价是如何处理文本中的<<的。通常,如果您使用XML发布任何内容,请务必查看预览以确保它看起来如何。顺便说一句,写得很好的问题。我会积极投票,但今天我的选票不足。 –

回答

1

你不需要xmlSchools类,你可以在xmlSchool_search类中引入List<of xmlSchool>类型的属性集合。
然后使用XmlArray属性来告诉序列化程序当前属性表示一个集合。

<XmlRoot(ElementName:="school_search")> 
Public Class xmlSchool_search 
    <XmlElement(ElementName:="summary")> 
    Public Property Summary As xmlSummary 

    <XmlArray(ElementName:="schools")> 
    Public Property Schools As List(Of xmlSchool) 
End Class 

<XmlType(ElementName:="summary")> 
Public Class xmlSummary 
    <XmlElement(ElementName:="total_schools")> 
    Public Property Total_schools As String 

    <XmlElement(ElementName:="category")> 
    Public Property Category As String 
End Class 

<XmlType(ElementName:="school")> 
Public Class xmlSchool 
    <XmlElement(ElementName:="school_id")> 
    Public Property School_id As String 

    <XmlElement(ElementName:="school_name")> 
    Public Property School_name As String 
End Class 

反序列化

Dim deserializer As New XmlSerializer(GetType(xmlSchool_search)) 
Dim search As xmlSchool_search = Nothing 

Using reader As New StreamReader(response.GetResponseStream()) 
    search = DirectCast(deserializer.Deserialize(reader), xmlSchool_search) 
End Using 

Dim schools As List(Of xmlSchool) = search.Schools 

因为你必须在属性getter和setter方法没有自定义逻辑,你可以使用属性速记

Public Property Name As String 
+0

谢谢,这是现货!这一切都有道理:) –

1

我喜欢解析与XML LINQ简单的XML

Imports System.Xml 
Imports System.Xml.Linq 
Module Module1 
    Const FILENAME As String = "c:\temp\test.xml" 
    Sub Main() 

     Dim doc As XDocument = XDocument.Load(FILENAME) 

     Dim search As Search = doc.Descendants("school_search").Select(Function(x) New Search() With { _ 
                      .total_schools = x.Descendants("total_schools").FirstOrDefault(), _ 
                      .category = x.Descendants("category").FirstOrDefault(), _ 
                      .schools = x.Descendants("school").Select(Function(y) New School With { _ 
                                 .name = y.Element("school_name"), _ 
                                 .id = y.Element("school_id") _ 
                                     }).ToList() 
                     }).FirstOrDefault() 
    End Sub 

End Module 
Public Class Search 
    Public total_schools As Integer 
    Public category As String 
    Public schools As List(Of School) 
End Class 
Public Class School 
    Public name As String 
    Public id As Integer 
End Class 
+0

谢谢你的回答,在我看来,这是一个非常干净的解决方案。我之所以接受以前的答案是因为我不习惯使用LINQ,而是因为我不习惯使用LINQ,所以我接受了以前的答案,但下次必须通过.NET时,我会仔细研究它,所以非常感谢。真的很感激它。 –

+0

通常xml文件具有不需要的额外级别。序列化你必须让这些类匹配xml文件。通过手动解析,您可以消除像摘要摘要一样的图层。 – jdweng