【问题标题】:How to easily de-serialize polymorphic types from XML to POCOs (using XML Schema)?如何轻松地将多态类型从 XML 反序列化为 POCO(使用 XML Schema)?
【发布时间】:2011-01-09 21:39:46
【问题描述】:

假设我想解析这些 XML 元素中的任何一个:

<Server                      hostName="foobar"                      />
<WebServer                   hostName="foobar"                      />
<WebServer                   hostName="foobar" listeningOnPort="80" />
<Server xsi:type="WebServer" hostName="foobar" listeningOnPort="80" />

遵守以下 XML Schema 声明:

<xsd:element name="Server" type="IServer" />
<xsd:element name="WebServer" substitutionGroup="Server" type="IWebServer" />

<xsd:complexType name="IServer">
  <xsd:attribute name="hostName" type="xsd:string" use="required" />
</xsd:complexType>

<xsd:complexType name="IWebServer">
  <xsd:complexContent>
    <xsd:extension base="IServer">
      <xsd:attribute name="listeningOnPort" type="xsd:int" use="optional" />
    </xsd:extension>
  </xsd:complexContent>
</xsd:complexType>

到这些类型的相应 CLR 对象:

class Server : IServer { .. }               // [CorrespondsTo("Server")]
class WebServer : Server, IWebServer { .. } // [CorrespondsTo("WebServer")]

interface IServer                           // [CorrespondsTo("IServer")]
{
    string HostName { get; set; }           // [CorrespondsTo("hostName")]
}

interface IWebServer : IServer              // [CorrespondsTo("IWebServer")]
{
    int? ListeningOnPort { get; set; }      // [CorrespondsTo("listeningOnPort")]
}

.NET 框架或任何成熟、轻量级的 XML 解析库中是否有任何东西可以在我不必编写大量代码的情况下实现这一目标?拥有 XML Schema 真的有助于 XML 到 CLR 类型的映射吗?

  • XML 到 CLR 类型映射的声明性解决方案会很好,例如通过 C# 属性。
  • 可选属性应正确转换为可为空的类型。
  • &lt;Server xsi:type="WebServer" ... /&gt; 应该产生一个 WebServer 对象。

【问题讨论】:

  • 我建议您创建一个简单的类层次结构,然后使用 XML Serializer 对其进行序列化;调整使某些元素成为属性并再次序列化;然后检查它是否不够好,尽管不匹配您的架构。

标签: c# xsd polymorphism xml-parsing xml-deserialization


【解决方案1】:

.NET 原生支持 XML 到 CLR 序列化。

有一个名为“XSD.exe”的命令行工具,它获取一系列 .xsd 文档并创建相应的 C# 对象。

http://msdn.microsoft.com/en-us/library/x6c1kb0s(VS.71).aspx

然后在代码中,使用 XmlSerializer 类进行序列化和反序列化。

http://msdn.microsoft.com/en-us/library/system.xml.serialization.xmlserializer.aspx

【讨论】:

  • 谢谢,这是一个好的开始。我有点失望 .NET 原生反序列化不支持可空类型,也不支持接口。如果我找不到让这些工作的方法,我会这样做并将反序列化的对象转换为我自己的对象模型(API)......这应该很容易。
  • 我接受这个答案不是因为它完全回答了我的问题,而是因为我看到 .NET 本身并不能提供我所寻求的东西——尽管如此,这足以让我的代码正常工作。
猜你喜欢
  • 1970-01-01
  • 2020-12-09
  • 1970-01-01
  • 2021-12-22
  • 1970-01-01
  • 1970-01-01
  • 2011-05-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多