C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

入れ子になった名前空間の同じ名前のクラスのシリアライズについ

[トピック内 5 記事 (1 - 5 表示)]  << 0 >>

■87305 / inTopicNo.1)  入れ子になった名前空間の同じ名前のクラスのシリアライズについ
  
□投稿者/ くろ (1回)-(2018/05/09(Wed) 13:53:55)

分類:[C#] 

WindowsFormアプリを
VisualStudioCommunity2017
.NetFramework4.6.1
C# で作成しています。

異なる分類の値を名前空間(AとB)に分けて同じ名前('設定')のクラスを作成してあります。
各々クラスのインスタンス単体で使用するには問題がなかったのですが、この2つの内容を1つのxmlファイルにするため、
名前空間 'C' に '保存クラス' を作成してシリアライズしようとしましたがエラーが発生します。

入れ子になった名前空間では同じ名前のクラスでシリアライズは出来ないのでしょうか?


以下、ソース

namespace プログラム名
{
    static class Program
    {
        (略)
        internal static void 保存処理(C.保存クラス c)
	{
	    var _obj = new Common.Settingsfile(c);
            var _sr = new System.Xml.Serialization.XmlSerializer(typeof(C.保存クラス));
            using (var _sw = new System.IO.StreamWriter(filename, false, new System.Text.UTF8Encoding(false)))
            {
                _sr.Serialize(_sw, _app);
                _sw.Flush();
            }
	}
    }

    namespace A
    {
	[Serializable]
	public class 設定
	{
	    (略)
	}
    }

    namespace B
    {
        [Serializable]
	public class 設定
	{
	    (略)
	}
    }

    namespace C
    {
        [Serializable]
        public class 保存クラス
	{
	    public A.設定 設定A { get; set; }
	    public B.設定 設定B { get; set; }

	    public 保存クラス()
	    {
	    }

	    public 保存クラス(A.設定 a, B.設定 b)
	    {
		this.設定A = new A.設定(a);
		this.設定B = new B.設定(a);
	    }
	}
    }
}


以下、エラー内容

内部例外 1:
InvalidOperationException: プロパティ 'testB' を反映中にエラーが発生しました。

内部例外 2:
InvalidOperationException: 型 'B.test' を反映中にエラーが発生しました。

内部例外 3:
InvalidOperationException: 型 'A.test' および 'B.test' は、名前空間 '' の XML 型名 'test' を使用しています。
この型の、一意の XML または名前空間を指定するには XML 属性を使用してください。


型名(クラス名)を変更せずに回避できる方法がありましたら、ご教授いただければ幸いです。

引用返信 編集キー/
■87317 / inTopicNo.2)  Re[1]: 入れ子になった名前空間の同じ名前のクラスのシリアライズについ
□投稿者/ Hongliang (640回)-(2018/05/10(Thu) 12:42:50)
// この状況は入れ子とは言わないと思います。

保存クラスの設定Aプロパティまたは設定Bプロパティ、あるいはその両方に、
[XmlElement(Namespace="何か適当な一意となる識別子文字列")]
public A.設定 設定A { ... }
を設定しろ、といった感じのが例外メッセージの内容ですね。

あるいは、A.設定クラスまたはB.設定クラスに、XmlRoot属性をつける方法もあります。
[XmlRoot(Namespace="何か適当な一意となる識別子文字列")]
public class 設定 { ... }

保存クラスも両設定クラスも手を入れることができない、ということなら、
XmlSerialzierをnewする際に、XmlAttributeOverridesクラスを使って、上記のような属性をシリアライズする側で設定することもできます。

なお上記のような属性を付けた場合、出力されるXMLにはxmlnsが出力されることになります。
当然デシリアライズする際にも必要なので、既存のXMLを読み足りたいという要望には応えられなさそうです。
引用返信 編集キー/
■87320 / inTopicNo.3)  Re[2]: 入れ子になった名前空間の同じ名前のクラスのシリアライズについ
□投稿者/ くろ (2回)-(2018/05/10(Thu) 15:29:52)
Hongliang さん

返答ありがとうございます。

> 保存クラスの設定Aプロパティまたは設定Bプロパティ、あるいはその両方に、
> [XmlElement(Namespace="何か適当な一意となる識別子文字列")]
> public A.設定 設定A { ... }
> を設定しろ、といった感じのが例外メッセージの内容ですね。

とりあえずこの方法でシリアライズ・デシリアライズができたのを確認いたしました。
ありがとうございました。


後学のために伺いたいのですが、

> なお上記のような属性を付けた場合、出力されるXMLにはxmlnsが出力されることになります。
> 当然デシリアライズする際にも必要なので、既存のXMLを読み足りたいという要望には応えられなさそうです。

確かにシリアライズされたXMLには'xmlns'が出力されていましたが、デシリアライズも出来ています。
デシリアライズの際に'xmlns'が原因で支障が出る場合というのはあるのでしょうか。
引用返信 編集キー/
■87321 / inTopicNo.4)  Re[3]: 入れ子になった名前空間の同じ名前のクラスのシリアライズについ
□投稿者/ Hongliang (641回)-(2018/05/10(Thu) 15:41:21)
> 確かにシリアライズされたXMLには'xmlns'が出力されていましたが、デシリアライズも出来ています。
> デシリアライズの際に'xmlns'が原因で支障が出る場合というのはあるのでしょうか。

例えばシリアライズした時に
<Hoge xmlns="fuga">3</Hoge>
と出力されるオブジェクトがあったとして、
<Hoge>3</Hoge>

<Hoge xmlns="piyo">3</Hoge>
をデシリアライズしても、Hogeの値には反映されない、ということです。
引用返信 編集キー/
■87327 / inTopicNo.5)  Re[4]: 入れ子になった名前空間の同じ名前のクラスのシリアライズについ
□投稿者/ ???? (1回)-(2018/05/11(Fri) 11:30:25)
No87321 (Hongliang さん) に返信

> 例えばシリアライズした時に
> <Hoge xmlns="fuga">3</Hoge>
> と出力されるオブジェクトがあったとして、
> <Hoge>3</Hoge>
> や
> <Hoge xmlns="piyo">3</Hoge>
> をデシリアライズしても、Hogeの値には反映されない、ということです。

シリアライズする対象のオブジェクト内に同じ名前があった場合等ということですね。

ありがとうございました。
解決済み
引用返信 編集キー/

このトピックをツリーで一括表示


トピック内ページ移動 / << 0 >>

このトピックに書きこむ