『究極のC#プログラミング』 Chapter18 LINQ to XML

XMLはツリー構造なので単なる列挙を扱うLINQ to Objectsとの相性は良くない。
そこでXML専用のLINQプロバイダーであるLINQ to XMLを使う。


XMLはDOMという悲惨な仕様のため面倒くさい
Xpathを使うと楽になるが、それでも名前空間に関する部分が面倒
E4Xを使えば素晴らしく簡単になる
C#では、ActionScriptのように言語仕様にE4Xが含まれるのではなく、LINQ to XMLという形でXMLを簡単に扱えるようになっている

// xml文書の定義
private const string xmldoc =
@"<?xml version='1.0'?>
<names xmlns='http://www.xxx.com/xxx/xxx'>
  <name id='X'>XXX</name>
  <name id='Y'>YYY</name>
  <name id='Z'>ZZZ</name>
</names>
";
// xml文書をLINQで処理

// xml文書の作成
var doc = XElement.Parse(xmldoc);

// 暗黙の型変換により、XNamespaceクラスのImplicitメソッドが使われて、文字列がXML名前空間を保持するオブジェクトに変換される
XNamespace ex = "http://www.xxx.com/xxx/xxx";

// ex + "name"は、演算子のオーバーロードにより、XNamespaceクラスのAdditionメソッドが使われて、
// XNamespaceオブジェクトとローカル名が結合されて、XNameオブジェクトが作成される
var query = from n in doc.Descendants(ex + "name")
            where n.Attribute("id").Value == "Y"
            select n;

foreach(var elem in query) Console.WriteLine(elem.Value);
// xml文書を作成する別の方法

XNamespace ex = "http://www.xxx.com/xxx/xxx";

// XElementのコンストラクタの
// 第一引数には、名前を指定する。
// 第二引数以降には、子ノードを指定する。属性(XAttribute), 要素(XElement), テキスト(string)のどれでも渡すことができる。
XElement doc = new XElement(ex + "person",
  new XElement(ex + "name", "Tanaka"),
  new XElement(ex + "age", "18"),
  new XElement(ex + "address", "Tokyo")
);

Console.WriteLine(doc.ToString());
<person xmlns="http://www.xxx.com/xxx/xxx">
  <name>Tanaka</name>
  <age>18</age>
  <address>Tokyo</address>
</person>