3

特定の基本型のカスタム コレクションをシリアル化するときに、要素名を定義できるかどうか疑問に思います。次の例を考えてみましょう (ここでは果物の例を使用しています:)):

[DataContract(Name = "Bowl")]
public class Bowl
{
    [DataMember]
    public List<Fruit> Fruits { get; set; }
}
[DataContract(Name = "Fruit")]
public abstract class Fruit
{
}
[DataContract(Name = "Apple", Namespace = "")]
public class Apple : Fruit
{
}
[DataContract(Name = "Banana", Namespace = "")]
public class Banana : Fruit
{
}

シリアル化する場合:

var bowl = new Bowl() { Fruits = new List<Fruit> { new Apple(), new Banana() } };
var serializer = new DataContractSerializer(typeof(Bowl), new[] { typeof(Apple), typeof(Banana) });
using (var ms = new MemoryStream())
{
    serializer.WriteObject(ms, bowl);
    ms.Position = 0;
    Console.WriteLine(System.Text.Encoding.UTF8.GetString(ms.ToArray()));
}

次の出力が得られます。

<Bowl xmlns="http://schemas.datacontract.org/2004/07/" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
  <Fruits>
    <Fruit i:type="Apple" xmlns="" />
    <Fruit i:type="Banana" xmlns="" />
  </Fruits>
</Bowl>

私が本当に欲しいのは、フルーツ要素が適切なクラス名に置き換えられた出力です。すなわち:

<Bowl xmlns="http://schemas.datacontract.org/2004/07/">
  <Fruits>
    <Apple />
    <Banana />
  </Fruits>
</Bowl>

XmlWriterで独自のロジックを作成することは可能DataContractSerializerですか?

4

1 に答える 1

3

xml 出力を細かく制御したい場合はXmlSerializer、 ではなくに対して注釈を付ける必要がありますDataContractSerializer。例えば:

using System;
using System.Collections.Generic;
using System.Xml.Serialization;

public class Bowl {
    [XmlArray("Fruits")]
    [XmlArrayItem("Apple", typeof(Apple))]
    [XmlArrayItem("Banana", typeof(Banana))]
    public List<Fruit> Fruits { get; set; }
}
public abstract class Fruit { }
public class Apple : Fruit { }
public class Banana : Fruit { }

static class Program {
    static void Main() {
        var ser = new XmlSerializer(typeof(Bowl));
        var obj = new Bowl {
            Fruits = new List<Fruit> {
                new Apple(), new Banana()
            }
        };
        ser.Serialize(Console.Out, obj);
    }
}
于 2012-11-16T10:15:30.327 に答える