4

BaseTypeをサブクラス化するさまざまな具象タイプのオブジェクトが入力されたリストがあります

WCFDataContractSerializerを使用しています

<Children>
    <BaseType xmlns:d3p1="http://schemas.datacontract.org/2004/07/Tasks"
              i:type="d3p1:ConcreteTypeA"></BaseType>
    <BaseType xmlns:d3p1="http://schemas.datacontract.org/2004/07/Tasks"
              i:type="d3p1:ConcreteTypeB"></BaseType>
</Children>

これを生成する方法はありますか

<Children>
    <ConcreteTypeA/>
    <ConcreteTypeB/>
</Children>

本当の目標は、ユーザーがメモリにロードするXMLを生成できるようにすることであり、ユーザーは、元のXMLを要求しても成功しないスキルレベルにあります。

4

1 に答える 1

7

DataContractSerializerは、出力を制御できるようには設計されていません。これは、高速で暗黙的であり、クラスの属性を簡単に指定できるように設計されています。

必要なのはXmlSerializerです。これにより、XML出力をより細かく制御できます。

以下の例では、プロパティ名から推測できる多くのことを指定しましたが、属性でそれらをオーバーライドできるという意味を与えるためだけであることに注意してください。実際、すべての属性が削除され、いくつかのKnownTypeAttributesが適用された場合、このクラス全体は問題なくシリアル化されると思いますが、テストはしていません。これで説明した正確なXMLが得られるかどうかはわかりませんが(Childrenの上にルート要素が作成されます)、これで正しい方向に進むことができれば幸いです。

XMLシリアル化を制御する属性

[XmlRoot(Namespace="")]
public class MyClass {

    [XmlArray("Children")]
    [XmlArrayItem("ConcreteTypeA", typeof(ConcreteTypeA))]
    [XmlArrayItem("ConcreteTypeB", typeof(ConcreteTypeB))]
    public BaseType[] Children {
        get;
        set;
    }

}

public class BaseType {
}

public class ConcreteTypeA : BaseType {
}

public class ConcreteTypeB : BaseType {
}

編集:私はちょうどテストしました、そしてそれはあなたが探していたものに非常に近い何かを生み出します。

void Main()
{

    var mc = new MyClass();
    mc.Children = new BaseType[] {
        new ConcreteTypeA(),
        new ConcreteTypeB(),
        new ConcreteTypeA(),
        new ConcreteTypeB()
    };

    var serializer = new XmlSerializer(typeof(MyClass));

    using ( var str = new StringWriter() ) {
        serializer.Serialize(str, mc);
        str.ToString().Dump();
    }

}

...生成します...(役に立たないxmlnsが上部から削除されました)

<MyClass>
  <Children>
    <ConcreteTypeA />
    <ConcreteTypeB />
    <ConcreteTypeA />
    <ConcreteTypeB />
  </Children>
</MyClass>
于 2010-04-10T03:04:02.140 に答える