2017-11-25 9 views
1

webrequest에서 오는 XML 문자열을 deserialize하려고하는데 반복 할 수있는 사용자 지정 개체 목록에 추가하는 데 문제가 있습니다. 이것과 나는 단지 내가 뭘 잘못하고 있는지 알아낼 수 없다, 이것은 내가 비슷한 것을 시도하고있는 처음이다. 그래서이 시점에서 나는 조금 우둔하다.XML 사용자 지정 개체 목록에 deserialize

<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입니다. mpty, 문제는 사용자 정의 클래스 내에 있다고 생각하지만 문제가 어디인지는 알 수 없습니다.

이 문제를 조사하는 데 시간을 할애 해 주셔서 감사합니다.

+0

게시 할 때 신중하게 모든 XML이 코드 형식으로되어 있는지 확인하십시오 (backticks 또는 블록 들여 쓰기 4 칸). 그렇게하지 않으면 태그가 자동으로 삭제되고 렌더링 된 질문에 나타나지 않습니다. 예외 메시지가 수정되었습니다. –

+0

짐에 대해 미안합니다, 편집 해 주셔서 감사합니다! –

+0

학습 과정의 모든 부분과 불행히도 SO markdown이 텍스트에서'<'로 무엇을하는지는 즉시 명백하지 않습니다. 원칙적으로 XML을 사용하여 게시물을 올리면 미리보기를보고 자신이 예상 한대로 보이는지 확인하십시오. BTW, 멋지게 작성된 질문. 나는 upvote하지만 오늘은 투표에서 벗어났다. –

답변

1

xmlSchools 클래스가 필요하지 않은 경우 List<of xmlSchool>의 속성으로 학교 컬렉션을 xmlSchool_search 클래스로 소개 할 수 있습니다.
그런 다음 XmlArray 특성을 사용하여 현재 속성이 컬렉션을 나타내는 지 serializer에 알립니다.

<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