質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
XML

XMLは仕様の1つで、マークアップ言語群を構築するために使われています。

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

.NET Framework

.NET Framework は、Microsoft Windowsのオペレーティングシステムのために開発されたソフトウェア開発環境/実行環境です。多くのプログラミング言語をサポートしています。

Q&A

解決済

3回答

5591閲覧

XMLファイルのデシリアライズ

nyahonyaho

総合スコア83

XML

XMLは仕様の1つで、マークアップ言語群を構築するために使われています。

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

.NET Framework

.NET Framework は、Microsoft Windowsのオペレーティングシステムのために開発されたソフトウェア開発環境/実行環境です。多くのプログラミング言語をサポートしています。

0グッド

1クリップ

投稿2016/09/07 07:14

「階層化された繰返し要素のXMLをデシリアライズする」
http://zero-config.com/dotnet/xmlserializer002.html

この入門サイト(?)の内容を改造します。
<user>と同じ階層に要素を追加してみます("admin"と名付けました)。

できたXML <?xml version="1.0" encoding="utf-8"?> <system-config> <system-name>XXXXX</system-name> <version>1.1</version> <users> <user id="0001"> <email>foo@example.com</email> <expired>2015/12/31</expired> </user> <user id="0002"> <email>bar@example.com</email> <expired>2015/09/30</expired> </user> <admin id="000a"> <email>foo@example.com</email> <expired>2015/12/31</expired> </admin> <admin id="000b"> <email>bar@example.com</email> <expired>2015/09/30</expired> </admin> </users> </system-config>

こうした場合でのクラス設計がわかりません。
"public class SystemConfig"の書き方がミソだとは思うのですが、色々試しても処理が通りません。

通らない例 /// <summary> /// システム設定 /// </summary> [System.Xml.Serialization.XmlRoot("system-config")] public class SystemConfig { /// <summary> /// システム名 /// </summary> [System.Xml.Serialization.XmlElement("system-name")] public string SystemName {get; set;} /// <summary> /// バージョン /// </summary> [System.Xml.Serialization.XmlElement("version")] public string Version { get; set; } /// <summary> /// ユーザ情報 /// </summary> [System.Xml.Serialization.XmlArray("users")] [System.Xml.Serialization.XmlArrayItem("user")] public List<Sample.Model.User> Users { get; set; } ///アドミニ情報 [System.Xml.Serialization.XmlArray("users")] [System.Xml.Serialization.XmlArrayItem("admin")] public List<Sample.Model.Admin> Admins{ get; set; } } ・ ・ ・ UserクラスをコピペしたAdminクラスを宣言

丸投げ気味な質問になってしまってますが、よろしくお願いします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

既にに解決しているようですが、XMLについて他のやり方も書き残します。
※質問時点のXMLの構造は適切ではないので、ishi9様の回答のようにroleを付け加えるのが一番いいです。

  • Classを自動で生成する方法

img]

  • Classを作成せずに動的にXMLを扱う方法
var str = @"<xml> ... </xml>" var xml = XDocument.Parse(str); var version = xml.Element("system-config").Element("version").Value; foreach (var x in xml.Element("system-config").Element("users").Elements("user")) { Console.WriteLine(x.Element("email").Value); } foreach (var x in xml.Element("system-config").Element("users").Elements("admin")) { Console.WriteLine(x.Element("email").Value); }

投稿2016/09/09 04:06

aglkjggg

総合スコア769

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

nyahonyaho

2016/09/13 02:06

わざわざありがとうございます。しかしちんぷんかんぷんなので、「ホニャララでググれ」的なことを教えていただけないでしょうか
aglkjggg

2016/09/14 20:20

Classを自動で生成する方法 については、 手動でクラスを書いているのかと思ったので、XMLをコピーした状態で「XMLをクラスとして貼り付ける」を選択すると自動でクラスが生成されるという意味でした。 何も考えずにXMLクラスを自動で生成してくれるので楽ですし、巨大かつ構造が複雑なXMLの場合にヒューマンエラーを防ぐことができます。 Classを自動で生成する方法 については、 System.Xml.Serialization.XmlSerializer を使うのではなく、 System.Xml.Linq.XDocument を使う方法もあるという紹介でした。 System.Xml.Linq.XDocument を使うと、classの生成が不要です。
nyahonyaho

2016/09/15 08:20

重ねてわざわざありがとうございます。
guest

0

ベストアンサー

usersに入れられるクラスは一種類だけです。他のクラスは入りません。(userとadminの共有はできない)
ですので、以下の様にUserクラスを拡張してみるのはいかがでしょうか?

c#

1 /// <summary> 2 /// ユーザ情報 3 /// </summary> 4 [Serializable] 5 public class User 6 { 7 /// <summary> 8 /// ID 9 /// </summary> 10 [System.Xml.Serialization.XmlAttribute("id")] 11 public string Id { get; set; } 12 /// <summary> 13 /// メールアドレス 14 /// </summary> 15 [System.Xml.Serialization.XmlElement("email")] 16 public string MailAddress {get; set;} 17 /// <summary> 18 /// 有効期限 19 /// </summary> 20 [System.Xml.Serialization.XmlElement("expired")] 21 public string Expired { get; set; } 22 23 // 以下を追加 24 25 /// <summary> 26 /// 役割 27 /// </summary> 28 [System.Xml.Serialization.XmlElement("role")] 29 public string Role { get; set; } 30 }

xml

1<?xml version="1.0" encoding="utf-8"?> 2<system-config> 3 <system-name>XXXXX</system-name> 4 <version>1.1</version> 5 <users> 6 <user id="0001"> 7 <email>foo@example.com</email> 8 <expired>2015/12/31</expired> 9 <role>user</role> 10 </user> 11 <user id="0002"> 12 <email>bar@example.com</email> 13 <expired>2015/09/30</expired> 14 <role>user</role> 15 </user> 16 <userid="000a"> 17 <email>foo@example.com</email> 18 <expired>2015/12/31</expired> 19 <role>admin</role> 20 </user> 21 <userid="000b"> 22 <email>bar@example.com</email> 23 <expired>2015/09/30</expired> 24 <role>admin</role> 25 </user> 26 </users> 27</system-config>

投稿2016/09/08 08:46

編集2016/09/08 08:48
ishi9

総合スコア1294

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ishi9

2016/09/08 09:21 編集

もうひとつ考えられるのはUsersとは別にAdminsを作ってしまう事です。 以下サンプル c# ///アドミニ情報 [System.Xml.Serialization.XmlArray("admins")] // ←ここをadminsにする [System.Xml.Serialization.XmlArrayItem("admin")] public List<Sample.Model.Admin> Admins{ get; set; } xml <?xml version="1.0" encoding="utf-8"?> <system-config> <system-name>XXXXX</system-name> <version>1.1</version> <users> <user id="0001"> <email>foo@example.com</email> <expired>2015/12/31</expired> </user> <user id="0002"> <email>bar@example.com</email> <expired>2015/09/30</expired> </user> </users> ←userはusersの中に入れる <admins> ←adminはadminsの中に入れる <admin id="000a"> <email>foo@example.com</email> <expired>2015/12/31</expired> </admin> <admin id="000b"> <email>bar@example.com</email> <expired>2015/09/30</expired> </admin> </admins> </system-config>
nyahonyaho

2016/09/09 02:40

で、できた。素直にXmlElementで作っていけばよかったのですね。ありがとうございます。
guest

0

C#については、ほとんど、門外漢なのですが、 users 要素に対する宣言が2つあり、余計なように見えます。

C#

1 /// <summary> 2 /// ユーザ情報 3 /// </summary> 4 [System.Xml.Serialization.XmlArray("users")] 5 [System.Xml.Serialization.XmlArrayItem("user")] 6 public List<Sample.Model.User> Users { get; set; } 7 ///アドミニ情報 8 [System.Xml.Serialization.XmlArrayItem("admin")] 9 public List<Sample.Model.Admin> Admins{ get; set; }

ではだめでしょうか?

投稿2016/09/07 12:59

mit0223

総合スコア3401

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問