LINT to XML 備忘録1でLINQ to XML を使用するサンプルを掲載しましたが、LINQ to XMLのために追加されたX*クラスの使用方法についての備忘録を掲載します。

LINQ to XML で使用されるX*クラスはSystem.Xml.Linq名前空間にあります。ルートクラスはXObjectで、主なクラスの継承階層は次のようになっています。

XObject
    |-XAttribute
    |-XNode
        |-XComment
        |-XContainer
        |    |-XElement
        |    |-XDocument
        |-XDocumentType
        |-XProcessingInstruction
        |-XText
             |-XCData

その他の有用なクラスとして、巨大なXElementを保存する場合XStreamingElementを使用できます。XStreamingElementはObjectから派生しています。サンプルはMSDNを参照して下さい。LINQ to XML 備忘録1で紹介した、ブロックごとにXMLを読み込む方法と併用することで、巨大なXMLファイルの変換を高いパフォーマンスで実行できます。

1. XMLドキュメントを作成する

XDocument, XElement, XAttribute, XDeclarationを使用してXMLドキュメントを作成します。

サンプルプログラムを掲載します。

public static void CreateXDocument()
{
    System.Xml.Linq.XDocument doc = CreateTestXDocument();
    doc.Save(@"D:\temp\CreateXDocument.xml");
    Console.WriteLine(doc.ToString());
}
public static XDocument CreateTestXDocument()
{
    System.Xml.Linq.XDocument doc =
           new XDocument(
                  new XDeclaration("1.0", "UTF-8", "yes"),
                  new XElement("Product",
                      new XAttribute("id", "RX78"),
                      new XAttribute("operator", "amuro"),
                      new XElement("name", "Gundam"),
                      new XElement("price", "1000"),
                      new XElement("material", "gundarium")
                  )
          );
    return doc;
}

出力されたファイルは次のようになります。

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<Product id="RX78" operator="amuro">
  <name>Gundam</name>
  <price>1000</price>
  <material>gundarium</material>
</Product>

2. XNamespaceを使用して名前空間を指定する

XNamespaceを使用することで、名前空間を設定できます。デフォルトネームスペースを定義するバージョンと、カスタムプリフィックス付のネームスペースを定義するサンプルを掲載します。

public static void TestXNamespace()
{
    XNamespace ns = "http://ns.handcraft.org/testnamespace";
    XElement e = new XElement(ns + "product", new XAttribute("id", "RX78"),
        new XElement(ns + "name", "Gundam"), new XElement("append", "nonamespace"));
    Console.WriteLine("デフォルト名前空間の場合");
    Console.WriteLine(e);

    Console.WriteLine(e.Name);

    XNamespace ns1 = "http://ns.handcraft.org/testnamespace";
    XElement e1 = new XElement(ns1 + "product",new XAttribute(XNamespace.Xmlns + "e1", ns), new XAttribute("id", "RX78"),
        new XElement(ns1 + "name", "Gundam"), new XElement("append", "nonamespace"));
    Console.WriteLine("接頭辞つきネームスペースを使用した場合");
    Console.WriteLine(e1);
}

実行結果が次のようになります。

デフォルト名前空間の場合
<product id="RX78" xmlns="http://ns.handcraft.org/testnamespace">
  <name>Gundam</name>
  <append xmlns="">nonamespace</append>
</product>
{http://ns.handcraft.org/testnamespace}product
接頭辞つきネームスペースを使用した場合
<e1:product xmlns:e1="http://ns.handcraft.org/testnamespace" id="RX78">
  <e1:name>Gundam</e1:name>
  <append>nonamespace</append>
</e1:product>

3. アノテーション

XObject.Annotation<T>()を使用すると、一種のメタ情報を各XObjectから派生されたクラスに付与することができます。

public static void AnnotationTest()
{
    XNamespace ns = "http://ns.handcraft.org/testnamespace";
    XElement e = new XElement(ns + "product", new XAttribute("id", "RX78"),
        new XElement(ns + "name", "Gundam"), new XElement("append", "nonamespace"));
    Console.WriteLine("デフォルト名前空間の場合");
    e.AddAnnotation(new Product());
    Product p = e.Annotation<Product>();
    Console.WriteLine(e);
}

4. XPathEvaluate, XPathSelectElements

XPathの拡張メソッドを使用しています。XPathの拡張メソッドはSystem.Xml.XPath.Extentionsに定義されています。

使用するファイルは次の内容になっているとします。

<?xml version="1.0" encoding="utf-8"?>
<products>
  <product id="product1" category="book">
	<name>Programing Something</name>
	<price>2000</price>
	<publishDate>2008/10/10</publishDate>
	<authors>
		<author>Tarou Book</author>
		<author>Hanako Book</author>
	</authors>
  </product>
  <product id="product2" category="book">
	<name>Administrating Something</name>
	<price>5000</price>
	<publishDate>2008/10/12</publishDate>
	<authors>
		<author>Kotarou Book1</author>
		<author>Kohanako Book2</author>
	</authors>
  </product>
  <product id="product3" category="novel">
	<name>Suspection novel</name>
	<price>500</price>
	<publishDate>2007/12/12</publishDate>
	<authors>
		<author>Jirou Tarou</author>
	</authors>
  </product>
  <product id="product4" category="novel">
	<name>Fantasy novel</name>
	<price>540</price>
	<publishDate>2008/9/14</publishDate>
	<authors>
		<author>Tarou Book</author>
	</authors>
  </product>
  <product id="product5" category="cram">
	<name>Study English</name>
	<price>2400</price>
	<publishDate>2008/9/14</publishDate>
	<authors>
		<author>English Tarou</author>
		<author>English Jirou</author>
	</authors>
  </product>
</products>

XPathEvaluateを使用したサンプルを掲載します。

public static void XPathEvaluate()
{
    XElement products = XElement.Load(@"D:\temp\products.xml");
    var result = (IEnumerable<Object>) products.XPathEvaluate("/product[@category='book']/name/text()");
    foreach (var item in result)
    {
        Console.WriteLine(item);
    }
}

実行結果は次のようになります。

Programing Something
Administrating Something

XPathSelectElementsを使用したサンプルを掲載します。

public static void XPathSelect()
{
    XElement products = XElement.Load(@"D:\temp\products.xml");
    var query = from c in products.XPathSelectElements("/product[@category='book']")
                orderby (string) c.Element("name")
                select c;
    foreach (var item in query)
    {
        Console.WriteLine(item);
    }
}

実行結果は次のようになります。

<product id="product2" category="book">
  <name>Administrating Something</name>
  <price>5000</price>
  <publishDate>2008/10/12</publishDate>
  <authors>
    <author>Kotarou Book1</author>
    <author>Kohanako Book2</author>
  </authors>
</product>
<product id="product1" category="book">
  <name>Programing Something</name>
  <price>2000</price>
  <publishDate>2008/10/10</publishDate>
  <authors>
    <author>Tarou Book</author>
    <author>Hanako Book</author>
  </authors>
</product>

説明は以上です。誤り、指摘点などがありましたらご連絡ください。