C# 使用已知的 XSD 从 XML 读取类型化对象

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2298637/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-07 01:12:12  来源:igfitidea点击:

Read typed objects from XML using known XSD

c#xmlcompact-frameworkxsdxmldocument

提问by Steven_W

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

我有以下(作为示例)XML 文件和 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:

然后是以下 C# 代码:

  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)

我将针对 WindowsMo​​bile 设备,但这应该不会对答案产生太大影响。(可以是 .NET 2.0 或 3.5 ... 不确定 Sstem.Xml.Linq 是否会有所帮助)

采纳答案by Steven_W

OK - Found the answer I was looking for.

好的 - 找到了我正在寻找的答案。

it is the XmlConvert class.

它是 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'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.

Marc 的答案在读取整个强类型类方面是正确的,但在这种情况下,我只想读取单个强类型元素/节点。

回答by marc_s

You need to do two steps:

你需要做两个步骤:

1) Take your XML schema file and run it through the xsd.exeutility (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:

1) 获取您的 XML 模式文件并通过xsd.exe实用程序运行它(它随 Windows SDK 一起提供 - 它位于C:\Program Files\Microsoft SDKs\Windows\v6.0A\Bin\或某些类似的路径中。这可以将 XSD 文件转换为 C# 类:

xsd /c yourfile.xsd

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

这应该为您提供一个文件yourfile.cs,其中包含一个表示该 XML 模式的类。

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

2) 现在,有了那个 C# 类,您应该能够将 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"
}

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

就这么简单!:-)