2017-11-25 168 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