web-dev-qa-db-ja.com

XMLシリアル化と名前空間プレフィックス

クラスをXMLにシリアル化して名前空間を追加できるが、その名前空間が使用するプレフィックスを定義できるC#の方法を探しています。

最終的には、次のXMLを生成しようとしています。

<myNamespace:Node xmlns:myNamespace="...">
  <childNode>something in here</childNode>
</myNamespace:Node>

DataContractSerializerXmlSerializerの両方で名前空間を追加できることは知っていますが、制御できないもので内部的にプレフィックスを生成するようです。これらのシリアライザーのいずれかで制御できますか(どちらでも使用できます)?

名前空間の生成を制御できない場合、独自のXMLシリアライザーを作成する必要があります。その場合、最適なものは何ですか?

56
Aaron Powell

名前空間のエイリアスを制御するには、XmlSerializerNamespacesを使用します。

[XmlRoot("Node", Namespace="http://flibble")]
public class MyType {
    [XmlElement("childNode")]
    public string Value { get; set; }
}

static class Program
{
    static void Main()
    {
        XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
        ns.Add("myNamespace", "http://flibble");
        XmlSerializer xser = new XmlSerializer(typeof(MyType));
        xser.Serialize(Console.Out, new MyType(), ns);
    }
}

実行時にnamespaceを変更する必要がある場合は、XmlAttributeOverridesを追加で使用できます。

102
Marc Gravell

型に名前空間があるスキーマから生成されたコードを使用する場合、この名前空間のオーバーライドはルートレベルに適用されますが、さまざまな型のタグにはクラスに関連付けられた名前空間があります。

生成された2つの異なるクラスを使用する必要がありましたが、通信先のサーバーに基づいて異なる名前空間を使用していました(私の管理下にないでください)。

ここで提供されているすべてのオーバーライドを試してみましたが、最終的にあきらめて、実際にかなりうまく機能する一種のブルートフォースメソッドを使用しました。私がしたことは、文字列にシリアル化することでした。次に、string.replaceを使用して名前空間を変更し、stringwriterを使用して文字列からストリームを送信します。応答についても同じです-文字列へのキャプチャ-名前空間を操作してから、文字列ライターから文字列をデシリアライズします。

洗練されていないか、すべての派手なオーバーライドを使用しているわけではありませんが、仕事は完了しています。

3
impangolin