views:

417

answers:

2

What's the easiest way in VB.NET to parse this XML?

Here's an example of the full source:

View Source XML

I believe that the XML can be read directly into a class structure that matches the XML's structure.

Let's take a bit of the XML from the above example,

  <?xml version="1.0" encoding="UTF-8" ?> 
- <kml xmlns="http://earth.google.com/kml/2.0"&gt;
- <Response>
  <name>1321 herbert street, Warren, MI</name> 
  <Status>X</Status> 
  </Response>
  </kml>

I thought I could use this code, taken from another SO posting, to convert the XML to corresponding objects

Imports System.IO
Imports System.Text

Public Class Xml

    Public Shared Function SerializeToXMLString(ByVal ObjectToSerialize As Object) As String
        Dim mem As MemoryStream = New MemoryStream()
        Dim ser As System.Xml.Serialization.XmlSerializer = New System.Xml.Serialization.XmlSerializer(ObjectToSerialize.GetType())
        ser.Serialize(mem, ObjectToSerialize)
        Dim ascii As ASCIIEncoding = New ASCIIEncoding()
        Return ascii.GetString(mem.ToArray())
    End Function

    Public Shared Function DeSerializeFromXMLString(ByVal TypeToDeserialize As System.Type, ByVal xmlString As String) As Object
        Dim bytes() As Byte = System.Text.Encoding.UTF8.GetBytes(xmlString)
        Dim mem As MemoryStream = New MemoryStream(bytes)
        Dim ser As System.Xml.Serialization.XmlSerializer = New System.Xml.Serialization.XmlSerializer(TypeToDeserialize)
        Return ser.Deserialize(mem)
    End Function

End Class

..but the problem is, how the heck do I define these objects-even for the scaled-back simple example?

For example, the kml part is confusing..

I started out with this class...

Public Class kml

    Public Class Response


        Public Name As String
        Public Status As String

    End Class

End Class

..but wen I run this code:

Dim kml As kml
kml = CType(Xml.DeSerializeFromXMLString(GetType(kml), XmlDoc.OuterXml), kml)

..I get a parsing error.

I also tried this:

Public Class kml

    Private _Response As New Response

    Public ReadOnly Property Response() As Response
        Get
            Return _Response
        End Get
    End Property

End Class

Public Class Response


    Public name As String
    Public Status As String

End Class

I know I'm probably way off here. Someone please push me in teh right direction...

thx

Follow up question.

How do I handle nested collections, for example, the Placemark collection in this example?

+1  A: 

Just get rid of Class Response, and use GetType(kml).

Basically, you don't need nested classes (though you may use them). Nested elements are represented as properties with name corresponding to element name; if property is itself of class type, it can have more nested elements (mapping to properties of that class, in turn). The only case where the name of the class itself matters is for the root element.

Pavel Minaev
After reading your comment, which I am trying to digest, I modified my code slightly after I noticed that my nested classes were not defined in the right order. Still o luck. re-reading your comment (again)...
Velika
+2  A: 

Your kml and Response classes should look like this:

  Public Class kml
        Private _Response As Response
        Public Property Response() As Response
            Get
                Return _Response
            End Get
            Set(ByVal value As Response)
                _Response = value
            End Set
        End Property
    End Class
    Public Class Response
        Private _name As String
        Public Property name() As String
            Get
                Return _name
            End Get
            Set(ByVal value As String)
                _name = value
            End Set
        End Property
        Private _Status As String
        Public Property Status() As String
            Get
                Return _Status
            End Get
            Set(ByVal value As String)
                _Status = value
            End Set
        End Property
    End Class

Then you can deserialize like this:

Dim serializer As New XmlSerializer(GetType(kml), "http://earth.google.com/kml/2.0")               
Dim result As kml = TryCast(serializer.Deserialize(mem), kml)
Fredrik Mörk
Thanks. It worked. Now let's see if I can build onto it to ready the whole bloody XML file. Thanks for your help
Velika