2017-11-25 15 views
1

Webリクエストから来たXML文字列をデシリアライズしようとしていますが、繰り返し処理できるカスタムオブジェクトのリストに追加する際に問題があります。これと私はちょうど何が間違っているのか分かりませんが、これは私がこれと似たようなことをしようとしている初めてのことです。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 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に対処するために作成したクラスです。だからここ

は私がデシリアライズしようとしているXMLであります

これは、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です私は問題がカスタムクラスの中にあると信じていますが、問題がどこにあるのか分かりません。

この問題を調査していただきありがとうございます。

+0

何かを転記するときXMLを含むXMLの場合、すべてのXMLがコード形式であることを確認してください(バッククォートまたはブロックを4つの空白で字下げしてください)。そうしないと、タグは黙って破棄され、レンダリングされた質問には表示されません。私は例外メッセージを修正しました。 –

+0

そのジムについては申し訳ありません、編集に感謝します! –

+0

学習プロセスのすべての部分ですが、残念ながらSOマークダウンがテキストで '<'を使って行うことはすぐには分かりません。原則として、XMLを使って何かを投稿する場合は、プレビューを見て、あなたの期待通りに見えるようにしてください。ところで、うまく書かれた質問。私はupvoteしたいと思いますが、私は今日の投票から外れています。 –

答えて

1

xmlSchoolsクラスが不要な場合は、タイプList<of xmlSchool>のプロパティとしてxmlSchool_searchクラスの学校コレクションを導入できます。
次に、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 

、プロパティのセッターとゲッターには、カスタム・ロジックを持っていないので、あなたは、プロパティの速記を使用することができます

私は、XML LINQを持つ単純なXMLを解析したい
Public Property Name As String 
+0

ありがとうございました!それはすべて今意味があります:) –

1

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に慣れていないので、あなたのソリューションの代わりに正しいものとして以前の答えを受け入れたが、次回に.NETを通過しなければならないときには、それを詳しく見ていきます。心から感謝する。 –

+0

多くの場合、xmlファイルには不要なレベルがあります。シリアライゼーションでは、クラスをxmlファイルと一致させる必要があります。手動解析では、要約を削除したように、レイヤーを削除することができます。 – jdweng

関連する問題