【问题标题】:C# serializing xsi:type and xsdC# 序列化 xsi:type 和 xsd
【发布时间】:2011-05-21 17:45:19
【问题描述】:

我的架构定义如下:

<?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:

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

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

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

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

【问题讨论】:

    标签: c# .net xml xml-serialization xsd


    【解决方案1】:

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

    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);
    }
    

    运行它会产生这个输出:

    <?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] 申请到任何拥有藏书的地方。例如,这可能是 web 方法中的参数。

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

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

    【讨论】:

    • 你知道如何序列化这个吗? xsi:type="cbl:SomeContent"
    【解决方案2】:

    @伊万洛佩兹

    不要使用派生类,而是使用XMLAttribute,如下图声明属性,然后赋值

    [XmlAttribute("type", Namespace = "http://www.w3.org/2001/XMLSchema-instance")]
    public string type;
    var document = new MyDocument 
    {
    type = "cbl:SomeContent";
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-10-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多