C# 序列化 xsi:type 和 xsd [英] C# serializing xsi:type and xsd

查看:41
本文介绍了C# 序列化 xsi:type 和 xsd的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个如下定义的架构:

I have a schema defined as follows:

<?xml version="1.0" encoding="utf-8"?>
<xs:schema id="Books" xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
  <xs:element name="Books" msdata:IsDataSet="true" msdata:Locale="en-US">
    <xs:complexType>
      <xs:choice minOccurs="0" maxOccurs="unbounded">
        <xs:element name="Book" type="MyBookType"></xs:element>
      </xs:choice>
    </xs:complexType>
  </xs:element>

  <xs:complexType name="MyBookType">
  ...
  </xs:complexType>

</xs:schema>

使用此架构和 xsd.exe,我生成将在序列化期间使用的类.上述模式生成的类在序列化时会生成以下 xml:

Using this schema and xsd.exe, I generate the classes that will be used during serialization. The class generated by the above schema produces the following xml when serialized:

<Books>
  <Book>
  ...
  </Book>
</Books>

此 xml 用于 SOAP 请求,另一端的服务需要以下 xml:

This xml is used in a SOAP request and the service on the other end expects the following xml:

<Books>
  <Book xsi:type="MyBookType">
  ...
  </Book>
</Books>

如何编辑我的架构以便 xsi:type 属性包含在序列化的 xml 中?

How can I edit my schema so that the xsi:type attribute is included in the serialized xml?

推荐答案

使用派生类型和 XmlInclude 属性.例如:

Use a derived type, and an XmlInclude attribute. For example:

public class Book
{
    public string Title;
    public string Author;
}

public class MyBookType : Book { }

[XmlInclude(typeof(MyBookType))]
[XmlRoot("Books")]
public class Books : List<Book> { }

public void Run()
{
    var b =  new Books();
    b.Add(new MyBookType
        {
            Title = "The Art of War",
            Author = "Sun Tzu"
        });
    b.Add(new MyBookType
        {
            Title = "Great Expectations",
            Author = "Charles Dickens"
        });

    var s = new XmlSerializer(typeof(Books));
    s.Serialize(Console.Out, b);
}

运行这个会产生这个输出:

Running this produces this output:

<?xml version="1.0" encoding="IBM437"?>
<Books xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
       xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Book xsi:type="MyBookType">
    <Title>The Art of War</Title>
    <Author>Sun Tzu</Author>
  </Book>
  <Book xsi:type="MyBookType">
    <Title>Great Expectations</Title>
    <Author>Charles Dickens</Author>
  </Book>
</Books>

由于您使用的是 SOAP 请求,因此我假设使用的是 ASMX,这意味着序列化是隐式发生的.您需要将 [XmlInclude] 应用到任何拥有书籍收藏的地方.例如,这可以是 webmethod 中的参数.

Since you're using a SOAP request, I'm assuming ASMX, which means the serialization happens implicitly. You will need to apply [XmlInclude] to whatever holds the collection of books. This could be a parameter in a webmethod, for example.

您可以自动生成适当的 XmlInclude 属性,从 XSD 和 WSDL 开始,如果您在 XSD 中定义类型,以及我在 C# 代码中说明的继承关系.

You can automatically generate the appropriate XmlInclude attribute, starting from XSD and WSDL, if you define the types in XSD, with the inheritance relationship I illustrated in C# code.

在 WSDL 中,请求消息可能采用 Books 类型,它是 Book 的集合.单独定义一个 MyBookType,它派生自 Book 但不扩展它.

In WSDL, the request message might take a Books type, which is a collection of Book. Separately, define a MyBookType which derives from Book but does not extend it.

这篇关于C# 序列化 xsi:type 和 xsd的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆