【问题标题】:Serialize derived class root as base class name with type将派生类根序列化为具有类型的基类名称
【发布时间】:2015-11-06 13:23:13
【问题描述】:

我无法实现这种序列化。我有这些课程

public class Data
{
    [XmlElement("Name")]
    public string Name { get; set; }
}

[XmlRoot("Data")]
public class DataA : Data
{
    [XmlElement("ADesc")]
    public string ADesc { get; set; }
}

[XmlRoot("Data")]
public class DataB : Data
{
    [XmlElement("BDesc")]
    public string BDesc { get; set; }
}

当我序列化 DataA 或 DataB 时,我应该得到以下结构中的 XML:

<Data xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="" i:type="DataA">
      <Name>A1</Name>
      <ADesc>Description for A</ADesc>
</Data>

<Data xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="" i:type="DataB">
      <Name>B1</Name>
      <BDesc>Description for b</BDesc>
</Data>

我得到的是下面的(没有 i:type="..." 和 xmlns="")

<Data xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
      <Name>A1</Name>
      <ADesc>Description for A</ADesc>
</Data>

<Data xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
      <Name>B1</Name>
      <BDesc>Description for b</BDesc>
</Data>

我不确定我在这里缺少什么。任何建议都会有所帮助。

  • 吉里哈

【问题讨论】:

标签: c# xml-serialization


【解决方案1】:

您应该为基类的 XML 序列化包括派生类型。

然后你可以为基类型创建一个序列化器,当你序列化任何派生类型时,它会添加 type 属性:(你现在甚至可以从派生类中删除 [Root] 属性)

[XmlInclude(typeof(DataA))]
[XmlInclude(typeof(DataB))]
[XmlRoot("Data", Namespace = Data.XmlDefaultNameSpace)]
public class Data
{
    public const string XmlDefaultNameSpace = "http://www.stackoverflow.com/xsd/Data";

    [XmlElement("Name")]
    public string Name { get; set; }
}

序列化:

DataA a = new DataA() { ADesc = "ADesc", Name = "A" };
DataB b = new DataB() { BDesc = "BDesc", Name = "B" };
new XmlSerializer(typeof(Data)).Serialize(Console.OpenStandardOutput(), a);
new XmlSerializer(typeof(Data)).Serialize(Console.OpenStandardOutput(), b);

这是 DataA 类序列化的输出

<?xml version="1.0"?>
<Data xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xsi:type="DataA" xmlns="http://www.stackoverflow.com/xsd/Data">
  <Name>A</Name>
  <ADesc xmlns="">ADesc</ADesc>

【讨论】:

  • 谢谢,我得到了 i:type 。但是我如何获得 xmlns="".. 这不是结果 XML。
  • 编辑我的答案。你想让命名空间为空吗?因为在这种情况下它不会打印出名称
  • 是的,我需要那个空的。但是我现在用 value 和 empty 进行了测试,在这两种情况下都不会打印
  • 我正在添加我的输出。我不喜欢这句话,但它对我有用:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-07-14
  • 1970-01-01
  • 1970-01-01
  • 2011-05-07
  • 1970-01-01
  • 1970-01-01
  • 2020-01-30
相关资源
最近更新 更多