2011年5月19日

XML文書をLINQで作成してみるサンプル

 「LINQ(Language INtegrated Query)を使うとXML文書をSQL風の構文で簡単に読むことができる」というのはよく聞く話ですが、実はXML文書を書くときの方が便利になっているのです。 ただこれはLINQの効果でなく、LINQ用に作られた新しいXMLクラス群の効果なのですけど。

 XML要素(タグ)の表現にDOMではSystem.Xml.XmlElementクラスを使用しましたが、LINQではSystem.Xml.Linq.XElementクラスを使用します。 このXElementクラスのコンストラクタが可変長引数を受け取れるようになっていて、コンストラクタを入れ子にして並べるだけで目的のXML文書が完成してしまうという目から鱗な効果をもたらします。

LINQ to XMLプログラム3の実装

 お題としてGundamList.xmlを出力するプログラム(GundamLinq3.cs)を作成してみました。
using System.Xml.Linq;

namespace GundamLinq
{
    class GundamLinq3
    {
        static void Main(string[] args)
        {
            // 名前空間を表すオブジェクトを用意
            XNamespace ns = "urn:gundam:anime";

            // XML文書を表すオブジェクトと同時に中身も生成
            XDocument doc = new XDocument(
                new XDeclaration("1.0", "shift_jis", "no"),
                new XDocumentType("gundamList", null, "GundamList.dtd", null),
                new XElement(ns + "gundamList",
                    new XElement(ns + "gundam",
                        new XAttribute("media", "TV"),
                        new XElement(ns + "name", "機動戦士ガンダム"),
                        new XElement(ns + "calendar", "0079",
                            new XAttribute("jpn", "宇宙世紀"),
                            new XAttribute("eng", "U.C.")
                        ),
                        new XElement(ns + "director", "富野由悠季")
                    ),
                    new XElement(ns + "gundam",
                        new XAttribute("media", "TV"),
                        new XElement(ns + "name", "機動戦士Zガンダム"),
                        new XElement(ns + "calendar", "0087",
                            new XAttribute("jpn", "宇宙世紀"),
                            new XAttribute("eng", "U.C.")
                        ),
                        new XElement(ns + "director", "富野由悠季")
                    )
                )
            );

            // ルート要素にコメントと子要素を追加
            doc.Root.Add(
                new XComment("中略"),
                new XElement(ns + "gundam",
                    new XAttribute("media", "TV"),
                    new XElement(ns + "name", "機動戦士ガンダム00 セカンドシーズン"),
                    new XElement(ns + "calendar", 2312,
                        new XAttribute("jpn", "西暦"),
                        new XAttribute("eng", "A.D.")
                    ),
                    new XElement(ns + "director", "水島精二")
                )
            );
            
            // XML文書をファイルに出力
            doc.Save(@"..\..\GundamList.xml");
        }
    }
}

 XElementクラスの素晴らしさはソースコードから一目瞭然でしょう。 その影でXNamespaceクラスが縁の下の力持ち的活躍をしているので着目してください。 これは複数の名前空間が混在する場合に威力を発揮します。


LINQ to XMLプログラム3の出力

 C#で書いた通りのXML文書がファイルに出力されました。 XDeclarationクラスに"utf-8"を指定しておくとUTF-8で出力されます。
<?xml version="1.0" encoding="shift_jis" standalone="no"?>
<!DOCTYPE gundamList SYSTEM "GundamList.dtd">
<gundamList xmlns="urn:gundam:anime">
 <gundam media="TV">
   <name>機動戦士ガンダム</name>
   <calendar jpn="宇宙世紀" eng="U.C.">0079</calendar>
   <director>富野由悠季</director>
 </gundam>
 <gundam media="TV">
   <name>機動戦士Zガンダム</name>
   <calendar jpn="宇宙世紀" eng="U.C.">0087</calendar>
   <director>富野由悠季</director>
 </gundam>
 <!--中略-->
 <gundam media="TV">
   <name>機動戦士ガンダム00 セカンドシーズン</name>
   <calendar jpn="西暦" eng="A.D.">2312</calendar>
   <director>水島精二</director>
 </gundam>
</gundamList>

 使ってみるとXMLの処理にはもうLINQしかありえないという印象でした。 ただそうなるとDOMSAXを試験範囲にしているXMLマスタープロフェッショナル資格の形骸化が心配です。

0 件のコメント:

コメントを投稿