- ベストアンサー
CシャープでのXML情報の取得
- C#でGUIとCLIアプリを作成する際、設定情報は外部のxmlに分割して保存する方法を紹介します。
- 分割したxmlをLinq to XMLを使用して情報の取得・書き換え・保存・作成を行うことができます。
- keyの値からvalueの値を取得する方法は、Linqを使って検索処理を行い、該当する値を取得することができます。
- みんなの回答 (1)
- 専門家の回答
質問者が選んだベストアンサー
- ベストアンサー
LINQ to XMLのオブジェクト構造の作成方法はわかったということで、タグがXElementに対応,属性がXAttributeに対応し、XElementがXAttributeを所有する、というデータのつながりは解っているかと思います。 XDocument や XElement からすぐ下に所属する子要素を取得するには Element や Elements メソッドを利用します。 階層に関係なく子孫のどこかにある要素を取得するばあいには Descendants メソッドも利用できます。 XElement から属性を取得するには Attribute や Attributes メソッドを利用します。 属性値を取得する際にどこまで厳密にチェックなどをするかにもよるので、書き方は様々ですが、たとえば以下のようにいろいろチェックしつつ探すことも出来ます。 // 「settingNode」が「appSettings1」タグに対応する XElement だとする。 var name = default(string); var addNodes = settingNode.Elements("add"); foreach (var addNode in addNodes) { var keyAttr = addNode.Attribute("key"); if (keyAttr == null) { continue; } if (keyAttr.Value != "国語") { continue; } var valueAttr = addNode.Attribute("value"); if (valueAttr == null) { throw new Exception("期待するデータがない"); } name = valueAttr.Value; } あるいは以下のように、さくっと取得することも出来ます。(取得出来なければnullが返る) XAttribute は string へのキャストを定義しているので、どの属性が存在しないかなどの判定が必要ないのであれば、キャストを利用してnullチェックを入れるよりシンプルな書き方ができます。 var name = settingNode .Elements("add") .Where(node => (string)node.Attribute("key") == "国語") .Select(node => (string)node.Attribute("value")) .FirstOrDefault(); また、質問中で「例えば「国語」を検索」という書き方をされているので1度だけでなく何度かデータを探索することもあるのかと思いますが、そうであればXElementのツリーを何度も検索するのは効率が悪いので、以下のように一旦Dictionaryに変換するなどしてからの方が良いかと思います。 var subjectDict = settingNode .Elements("add") .ToDictionary(node => (string)node.Attribute("key"), node => (string)node.Attribute("value")); subjectDict.TryGetValue("国語", out name);
お礼
回答ありがとうございます。 xmlファイルを読み込み回答のプログラムを実行してみたところ、 問題なく取得できました。 仰る通りに探索は何度もするのでDictionary変換して、 TryGetValueメソッドを使用するのはとても良いですね。 速く、1行で呼び出しができるのは分かり易いです。 これで次に進めそうです。有難うございました。