Read typed objects from XML using known XSD

43,718

Solution 1

OK - Found the answer I was looking for.

it is the XmlConvert class.

     var el_date = (XmlElement)el_root.SelectSingleNode("./DateVal");
     //WANTED: el_date.Value = 2010-02-18 01:02:03 (as a DateTime Object)
     var val_date = XmlConvert.ToDateTime(el_date.InnerText);
     //ACTUAL: el_date.InnerText="2010-02-18T01:02:03"

     var el_duration = (XmlElement)el_root.SelectSingleNode("./TimeVal");
     //WANTED: el_date.Value = 10 hours, 5 minutes, 3 seconds (as a TimeSpan Object)
     var val_duration = XmlConvert.ToTimeSpan(el_duration.InnerText);
     //ACTUAL: el_date.InnerText="PT10H5M3S"

Marc's answer was correct in terms of reading in a whole strongly-typed class, but in this case I only wanted to read a single strongly-typed element/node.

Solution 2

You need to do two steps:

1) Take your XML schema file and run it through the xsd.exe utility (which comes with the Windows SDK - it's in C:\Program Files\Microsoft SDKs\Windows\v6.0A\Bin\ or some similar path. This can turn the XSD file into a C# class:

xsd /c yourfile.xsd

This should give you a file yourfile.cs which contains a class representing that XML schema.

2) Now, armed with that C# class, you should be able to just deserializing the XML file into an instance of your new object:

XmlSerializer ser = new XmlSerializer(typeof(foo));

string filename = Path.Combine(FilePath, "SimpleFields.xml");

foo myFoo = ser.Deserialize(new FileStream(filename, FileMode.Open)) as foo;

if (myFoo != null)
{
   // do whatever you want with your "foo"
}

That's about as simple as it gets! :-)

Share:
43,718
Steven_W
Author by

Steven_W

Updated on February 20, 2020

Comments

  • Steven_W
    Steven_W about 4 years

    I have the following (as an example) XML file and XSD.

    <?xml version="1.0" encoding="utf-8" ?>
    <foo>
      <DateVal>2010-02-18T01:02:03</DateVal>
      <TimeVal>PT10H5M3S</TimeVal>
    </foo>
    

    and

    version="1.0" encoding="utf-8"?>
    <xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
      <xs:element name="foo">
        <xs:complexType>
          <xs:sequence>
            <xs:element name="DateVal" type="xs:dateTime" />
            <xs:element name="TimeVal" type="xs:duration" />
          </xs:sequence>
        </xs:complexType>
      </xs:element>
    </xs:schema>
    

    Then the following C# code:

      static void Main(string[] args)
      {
         XmlDocument xd = new XmlDocument();
         XmlSchema xs;
         using (var fs = File.OpenRead(FilePath + "SimpleFields.xsd"))
         {
            xs = XmlSchema.Read(fs, null);
         }
    
         xd.Schemas.Add(xs);
         xd.Load((FilePath + "SimpleFields.xml"));
         xd.Validate(null);
    
         var el_root = xd.DocumentElement;
    
         var el_date = (XmlElement)el_root.SelectSingleNode("./DateVal");
         //WANTED: el_date.Value = 2010-02-18 01:02:03 (as a DateTime Object)
         //ACTUAL: el_date.InnerText="2010-02-18T01:02:03"
    
         var el_duration = (XmlElement)el_root.SelectSingleNode("./TimeVal");
         //WANTED: el_date.Value = 10 hours, 5 minutes, 3 seconds (as a TimeSpan Object)
         //ACTUAL: el_date.InnerText="PT10H5M3S"
    
         Console.WriteLine("DONE");
         Console.ReadLine();
      }
    

    How can I read the data as strongly typed objects ?

    I will be targetting a WindowsMobile device, but this shouldn't need to affect the answer too much. (can be .NET 2.0 or 3.5 ... Not sure if Sstem.Xml.Linq will help or not)