Чтение типизированных объектов из XML с использованием известного XSD
У меня есть следующий (как пример) XML файл и XSD.
<?xml version="1.0" encoding="utf-8" ?>
<foo>
<DateVal>2010-02-18T01:02:03</DateVal>
<TimeVal>PT10H5M3S</TimeVal>
</foo>
и
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>
Затем следующий код С#:
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();
}
Как я могу прочитать данные как сильно типизированные объекты?
Я буду нацеливать устройство WindowsMobile, но это не должно сильно влиять на ответ. (может быть .NET 2.0 или 3.5... Не уверен, что Sstem.Xml.Linq поможет или нет)
Ответы
Ответ 1
OK - нашел ответ, который я искал.
это класс XmlConvert.
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 был правильным с точки зрения чтения во всем строго типизированном классе, но в этом случае мне хотелось только прочитать один сильно типизированный элемент/ node.
Ответ 2
Вам нужно сделать два шага:
1) Возьмите XML файл схемы и запустите его с помощью утилиты xsd.exe
(которая поставляется с Windows SDK - она находится в C:\Program Files\Microsoft SDKs\Windows\v6.0A\Bin\
или аналогичном пути. Это может превратить XSD файл в класс С#:
xsd /c yourfile.xsd
Это даст вам файл yourfile.cs
, который содержит класс, представляющий эту XML-схему.
2) Теперь, вооруженный этим классом С#, вы должны просто десериализовать XML файл в экземпляр вашего нового объекта:
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"
}
Это примерно так же просто, как и получается!:-)