Read typed objects from XML using known XSD
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! :-)
Steven_W
Updated on February 20, 2020Comments
-
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)