具有不同类型但元素名称和 i:type 属性相同的 XMLArray

XMLArray with different types but same element name and i:type attribute

我正在尝试将我拥有的一些数据序列化为这种 XML 格式,但无法实现相同的格式。

所需的 XML 输出如下:

<?xml version="1.0" encoding="utf-8"?>
<Root xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
  <Datas>
    <Data xmlns="" i:type="DataA">
      <Name>A1</Name>
      <ADesc>Description for A</ADesc>
    </Data>
    <Data xmlns="" i:type="DataB">
      <Name>B1</Name>
      <BDesc>Description for b</BDesc>
    </Data>
  </Datas>
</Root>

我为连载创建的类如下:

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

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

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

[XmlRoot("Root")]
public class Root
{
    [XmlArray("Datas")]
    [XmlArrayItem(Type = typeof(Data))]
    [XmlArrayItem(Type = typeof(DataA))]
    [XmlArrayItem(Type = typeof(DataB))]
    public List<Data> Datas { get; set; }
}

我使用以下方法进行序列化:

internal static string Serialize(Root obj)
{
    var ns = new XmlSerializerNamespaces();
    ns.Add("i", "http://www.w3.org/2001/XMLSchema-instance");

    XmlSerializer xmlSerializer = new XmlSerializer(typeof(Root));

    using (StringWriter textWriter = new StringWriter())
    {
        xmlSerializer.Serialize(textWriter, obj, ns);
        return textWriter.ToString();
    }
}

但我得到的输出是这样的(这是不正确的):

<?xml version="1.0" encoding="utf-8"?>
<Root xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
  <Datas>
    <DataA>
      <Name>A1</Name>
      <ADesc>Description for A</ADesc>
    </DataA>
    <DataB>
      <Name>B1</Name>
      <BDesc>Description for b</BDesc>
    </DataB>
  </Datas>
</Root>

为了使用 XmlSerializer 生成 {http://www.w3.org/2001/XMLSchema-instance}type 属性,您需要为 [=15] 的所有子 class 和 XXX 附加 [XmlInclude(typeof(XXX))] =] 到对象图中某处的声明类型,即 Root class 或 Data class 本身:

//[XmlInclude(typeof(DataA))]  /* Could also go here if you prefer. */
//[XmlInclude(typeof(DataB))]  /* Could also go here if you prefer. */
public class Data
{
    [XmlElement("Name")]
    public string Name { get; set; }
}

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

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

[XmlRoot("Root")]
[XmlInclude(typeof(DataA))]
[XmlInclude(typeof(DataB))]
public class Root
{
    [XmlArray("Datas")]
    public List<Data> Datas { get; set; }
}

有关详细信息,请参阅 Troubleshooting Common Problems with the XmlSerializer and also Xsi:type Attribute Binding Support 中的声明序列化类型