今回は、LINQ to XMLの特徴の一つであるである関数型構築についてメモ。
以前の内容は以下から見れます。よろしければご参照くださいませ。
サンプルコードは、まとめてCodePlexにアップしてます。
- いろいろ備忘録日記 サンプルソース 置き場
LINQ to XMLには、関数型構築という仕組みがあり
XMLツリーを簡単に構築する事が出来るようになっています。
関数型構築って何?という感じですが、イメージとしてXElementクラスの
コンストラクタを利用して、XMLの要素を数珠つなぎで設定していく方法です。
以下のような感じです。
var doc = new XDocument ( new XElement ( "RootElement", new XElement("ChildElement", "ChildValue1"), new XElement("ChildElement", "ChildValue2"), new XElement("ChildElement", "ChildValue3"), ) );
XDocumentのコンストラクタに指定しているXElementがルート要素となります。
XDocumentはXMLの仕様に従い、ルート要素を一つしか指定出来ません。
上記は以下のXMLツリーを構築します。
<RootElement> <ChildElement>ChildValue1</ChildElement> <ChildElement>ChildValue2</ChildElement> <ChildElement>ChildValue3</ChildElement> </RootElement>
子要素を指定する場合、以下の規則で処理されます。
(http://msdn.microsoft.com/ja-jp/library/vstudio/bb387089.aspx)
- 文字列はテキストコンテンツとして扱われる
- XElementは子要素として扱われる
- XAttributeは属性要素として扱われる
- XProcessingInstruction, XComment, XTextは子コンテンツとして扱われる
- IEnumerableは列挙され、その結果にこれらの規則が再帰的に適用される
- 上記以外のその他の型の場合、ToStringメソッドが呼ばれテキストコンテンツとして扱われる
当然、構築部分でもLINQが利用出来ます。
以下は、同じXMLツリーが構築されます。
var doc = new XDocument ( new XElement ( "RootElement", from value in new []{ "ChildValue1", "ChildValue2", "ChildValue3" } select new XElement("ChildElement", value) ) );
以下、サンプルです。
#region LinqSamples-52 /// <summary> /// LINQ to XMLのサンプルです。 /// </summary> /// <remarks> /// XDocumentオブジェクトを関数型構築するサンプルです。 /// </remarks> public class LinqSamples52 : IExecutable { public void Execute() { // // XDocumentは複数のコンストラクタを持っているが // 以下を利用すると、関数型構築が行える. // 関数型構築とは、単一のステートメントでXMLツリーを作成するための機能である。 // (XElementクラスのコンストラクタを用いる) // // public XDocument(object[]) // public XDocument(XDeclaration, object[]) // // XDocumentを起点として関数型構築を行う場合 // ルート要素となるXElementを作成し、その子要素に // 様々な要素を設定する. // // 例: // var doc = new XDocument // ( // new XElement // ( // "RootElement", // new XElement("ChildElement", "ChildValue1"), // new XElement("ChildElement", "ChildValue2"), // new XElement("ChildElement", "ChildValue3") // ) // ); // // 上記例は、以下のXMLツリーを構築する. // <RootElement> // <ChildElement>ChildValue1</ChildElement> // <ChildElement>ChildValue2</ChildElement> // <ChildElement>ChildValue3</ChildElement> // </RootElement> // var doc = MakeDocument(); Console.WriteLine(doc); } XDocument MakeDocument() { var doc = new XDocument ( new XDeclaration("1.0", "utf-8", "yes"), new XElement("Persons", MakePersonElements()) ); return doc; } IEnumerable<XElement> MakePersonElements() { var names = new []{ "foo", "bar", "baz" }; var query = from name in names select new XElement ( "Person", new XAttribute("name", name), string.Format("VALUE-{0}", name) ); return query; } } #endregion
実行結果は以下のようになります。
VALUE-foo VALUE-bar VALUE-baz
以下、参照リソースです。
================================
過去の記事については、以下のページからご参照下さい。
- いろいろ備忘録日記まとめ
サンプルコードは、以下の場所で公開しています。
- いろいろ備忘録日記サンプルソース置き場