2

Is it possible to deserialize DataTable to custom Class? One of soap requests return DataTable in this format

<xs:schema xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" id="NewDataSet">
  <xs:element name="NewDataSet" msdata:IsDataSet="true" msdata:MainDataTable="geolocation" msdata:UseCurrentLocale="true">
    <xs:complexType>
      <xs:choice minOccurs="0" maxOccurs="unbounded">
        <xs:element name="geolocation">
          <xs:complexType>
            <xs:sequence>
              <xs:element name="Latitude" type="xs:float" minOccurs="0"/>
              <xs:element name="Longitude" type="xs:float" minOccurs="0"/>
            </xs:sequence>
          </xs:complexType>
        </xs:element>
      </xs:choice>
    </xs:complexType>
  </xs:element>
</xs:schema>
<diffgr:diffgram xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" xmlns:diffgr="urn:schemas-microsoft-com:xml-diffgram-v1">
  <NewDataSet xmlns="">
     <geolocation diffgr:id="geolocation" msdata:rowOrder="0">
       <Latitude>48.8186</Latitude>
       <Longitude>28.4681</Longitude>
     </geolocation>
     ...
  </NewDataSet>
</diffgr:diffgram>

I would like to deserialize it into an array of

public class Geolocation {
    public double latitude { get; set; }
    public double longitude { get; set; }
}

using XmlSerializer

XmlSerializer serializer = new XmlSerializer(typeof(Geolocation[]))
var Geolocations = (Geolocation)serializer.Deserialize(stream);

Edit: I tried to do something like this:

public class Geolocation {
    [XmlElement("Latitude")]
    public double Latitude { get; set; }
    [XmlElement("Longitude")]
    public double Longitude { get; set; }
}

but this didnt work

Almis
  • 3,684
  • 2
  • 28
  • 58

3 Answers3

2

With the help of aevitas and some more research I finally managed to do it, first write your service references like this

public class DataTable
{
    [XmlElement(ElementName = "schema", Namespace = "http://www.w3.org/2001/XMLSchema")]
    public Schema Schema { get; set; }
    [XmlElement(ElementName = "diffgram", Namespace="urn:schemas-microsoft-com:xml-diffgram-v1")]
    public Diffgram Diffgram { get; set; }
}

public class Schema
{
    [XmlElement(ElementName = "element", Namespace = "http://www.w3.org/2001/XMLSchema")]
    public Element Element { get; set; }
}

public class Element
{
    [XmlElement(ElementName = "complexType", Namespace = "http://www.w3.org/2001/XMLSchema")]
    public ComplexType ComplexType { get; set; }
    [XmlAttribute(AttributeName = "name", Namespace = "http://www.w3.org/2001/XMLSchema")]
    public String Name { get; set; }
}

public class ComplexType
{
    [XmlElement(ElementName = "choice", Namespace = "http://www.w3.org/2001/XMLSchema")]
    public Choice Choice { get; set; }
    [XmlElement(ElementName = "sequence", Namespace = "http://www.w3.org/2001/XMLSchema")]
    public Sequence Sequence { get; set; }
}

public class Sequence
{
    [XmlElement(ElementName = "element", Namespace = "http://www.w3.org/2001/XMLSchema")]
    public Element[] Elements { get; set; }
}

public class Choice
{
    [XmlElement(ElementName = "element", Namespace = "http://www.w3.org/2001/XMLSchema")]
    public Element Element { get; set; }
}

public classDiffgram
{
    [XmlElement(ElementName = "NewDataSet", Namespace = "")]
    public NewDataSet NewDataSet { get; set; }
}

public class NewDataSet
{
    [XmlElement("geolocation")]
    public Geolocation[] Geolocations { get; set; }
}

public class Geolocation
{
    [XmlElement("Latitude")]
    public double Latitude { get; set; }
    [XmlElement("Longitude")]
    public double Longitude { get; set; }
}

And then just write

// Namespace url is optional
XmlSerializer serializer = new XmlSerializer(typeof(DataTable), "http://example.com");
DataTable dt = (DataTable)serializer.Deserialize(stream);
Community
  • 1
  • 1
Almis
  • 3,684
  • 2
  • 28
  • 58
0

For the XmlSerializer to work, you will need a C# class that is properly decorated and matches the XML.

For example, Microsoft provides the following sample:

public class PurchaseOrder
{
    public Address MyAddress;
}
public class Address
{
    public string FirstName;
}

For the following XML:

<PurchaseOrder>
    <Address>
        <FirstName>George</FirstName>
    </Address>
</PurchaseOrder>

So in your case, you'd declare a NewDataSet class containing a Geolocation object (or a collection thereof, if you expect to receive multiple) which contains a Latitude and Longitude double.

Make sure you decorate the relevant types properly (like you have in your sample), and deserialize it as you demonstrated in your question.

It should work that way.

aevitas
  • 3,753
  • 2
  • 28
  • 39
  • but it starts with `diffgr:diffgram` how I can declare such class? – Almis Apr 29 '15 at 11:57
  • @Almis See [this question](http://stackoverflow.com/questions/2339782/xml-serialization-and-namespace-prefixes) for more details on that. – aevitas Apr 29 '15 at 12:20
0

You need a parent with a array or List<> object

    public class Root
    {
        [XmlElement("Geolocation")]
        List<Geolocation> Geolocation { get; set; }
    }
    public class Geolocation
    {
        [XmlElement("Latitude")]
        public double Latitude { get; set; }
        [XmlElement("Longitude")]
        public double Longitude { get; set; }
    }
jdweng
  • 33,250
  • 2
  • 15
  • 20