C# での XML ツリーの作成 (LINQ to XML)
更新 : November 2007
ここでは、C# での XML ツリーの作成について説明します。
LINQ クエリの結果を XElement のコンテンツとして使用する方法については、「関数型構築 (LINQ to XML)」を参照してください。
要素の構築
XElement コンストラクタと XAttribute コンストラクタの署名を使用すると、要素または属性のコンテンツを引数としてコンストラクタに渡すことができます。いずれかのコンストラクタは任意の数の引数を受け取るため、任意の数の子要素を渡すことができます。もちろん、それらの子要素のそれぞれに、さらに子要素を含めることもできます。いずれの要素にも、任意の数の属性を追加できます。
XNode オブジェクト (XElement を含む) や XAttribute オブジェクトの追加時に、新しいコンテンツに親がない場合、単にオブジェクトが XML ツリーにアタッチされます。新しいコンテンツに既に親があり、別の XML ツリーの一部となっている場合は、新しいコンテンツが複製され、新しく複製されたコンテンツが XML ツリーにアタッチされます。このトピックの最後の例では、この動作について説明します。
contactsXElement を作成するには、次のコードを使用できます。
XElement contacts =
new XElement("Contacts",
new XElement("Contact",
new XElement("Name", "Patrick Hines"),
new XElement("Phone", "206-555-0144"),
new XElement("Address",
new XElement("Street1", "123 Main St"),
new XElement("City", "Mercer Island"),
new XElement("State", "WA"),
new XElement("Postal", "68042")
)
)
);
適切にインデントされていれば、XElement オブジェクトを構築するコードは、基になる XML の構造によく似ています。
Visual Basic には、XML ツリーを作成する方法がもう 1 つあります。XML リテラルとして、Visual Basic プログラムに XML を直接組み込む方法です。詳細については、「Visual Basic の XML リテラルの概要」を参照してください。
XElement コンストラクタ
XElement クラスは、関数型構築で次のコンストラクタを使用します。XElement のコンストラクタはこれ以外にも存在しますが、関数型構築に使用されないものはこの一覧に示していません。
コンストラクタ |
説明 |
---|---|
XElement(XName name, object content) |
XElement を作成します。name パラメータには要素の名前を指定し、content には要素のコンテンツを指定します。 |
XElement(XName name) |
|
XElement(XName name, params object[] content) |
指定した名前で XName を初期化して、XElement を作成します。属性や子要素が、パラメータ リストのコンテンツから作成されます。 |
content パラメータは非常に柔軟です。XElement の有効な子オブジェクトの型すべてがサポートされています。このパラメータで渡されるさまざまな型のオブジェクトには、次の規則が適用されます。
文字列はテキスト コンテンツとして追加されます。
XElement は子要素として追加されます。
XAttribute は属性として追加されます。
XProcessingInstruction、XComment、または XText は、子コンテンツとして追加されます。
IEnumerable は列挙され、その結果にこれらの規則が再帰的に適用されます。
その他の型に対しては ToString メソッドが呼び出され、その結果がテキスト コンテンツとして追加されます。
コンテンツを持つ XElement の作成
単純コンテンツが含まれる XElement は、1 回のメソッド呼び出しで作成できます。そのためには、次のように、コンテンツを 2 番目のパラメータとして指定します。
XElement n = new XElement("Customer", "Adventure Works");
Console.WriteLine(n);
この例では次の出力が生成されます。
<Customer>Adventure Works</Customer>
任意の型のオブジェクトをコンテンツとして渡すことができます。たとえば、次のコードでは、浮動小数点数がコンテンツとして含まれる要素を作成します。
XElement n = new XElement("Cost", 324.50);
Console.WriteLine(n);
この例では次の出力が生成されます。
<Cost>324.5</Cost>
浮動小数点数はボックス化されてコンストラクタに渡されます。ボックス化された数は文字列に変換され、要素のコンテンツとして使用されます。
子要素を持つ XElement の作成
XElement クラスのインスタンスをコンテンツ引数として渡すと、コンストラクタによって、子要素を持つ要素が作成されます。
XElement shippingUnit = new XElement("ShippingUnit",
new XElement("Cost", 324.50)
);
Console.WriteLine(shippingUnit);
この例では次の出力が生成されます。
<ShippingUnit>
<Cost>324.5</Cost>
</ShippingUnit>
複数の子要素を持つ XElement の作成
複数の XElement オブジェクトをコンテンツとして渡すことができます。各 XElement オブジェクトは、子要素として格納されます。
XElement address = new XElement("Address",
new XElement("Street1", "123 Main St"),
new XElement("City", "Mercer Island"),
new XElement("State", "WA"),
new XElement("Postal", "68042")
);
Console.WriteLine(address);
この例では次の出力が生成されます。
<Address>
<Street1>123 Main St</Street1>
<City>Mercer Island</City>
<State>WA</State>
<Postal>68042</Postal>
</Address>
上の例を次のように拡張すると、完全な XML ツリーを作成できます。
XElement contacts =
new XElement("Contacts",
new XElement("Contact",
new XElement("Name", "Patrick Hines"),
new XElement("Phone", "206-555-0144"),
new XElement("Address",
new XElement("Street1", "123 Main St"),
new XElement("City", "Mercer Island"),
new XElement("State", "WA"),
new XElement("Postal", "68042")
)
)
);
Console.WriteLine(contacts);
この例では次の出力が生成されます。
<Contacts>
<Contact>
<Name>Patrick Hines</Name>
<Phone>206-555-0144</Phone>
<Address>
<Street1>123 Main St</Street1>
<City>Mercer Island</City>
<State>WA</State>
<Postal>68042</Postal>
</Address>
</Contact>
</Contacts>
空要素の作成
空の XElement を作成する場合は、コンストラクタにコンテンツを渡しません。次の例では、空要素を作成します。
XElement n = new XElement("Customer");
Console.WriteLine(n);
この例では次の出力が生成されます。
<Customer />
アタッチと複製
既に説明したように、XNode オブジェクト (XElement を含む) や XAttribute オブジェクトの追加時に、新しいコンテンツに親がない場合、単にオブジェクトが XML ツリーにアタッチされます。新しいコンテンツに既に親があり、別の XML ツリーの一部となっている場合は、新しいコンテンツが複製され、新しく複製されたコンテンツが XML ツリーにアタッチされます。
// Create a tree with a child element.
XElement xmlTree1 = new XElement("Root",
new XElement("Child1", 1)
);
// Create an element that is not parented.
XElement child2 = new XElement("Child2", 2);
// Create a tree and add Child1 and Child2 to it.
XElement xmlTree2 = new XElement("Root",
xmlTree1.Element("Child1"),
child2
);
// Compare Child1 identity.
Console.WriteLine("Child1 was {0}",
xmlTree1.Element("Child1") == xmlTree2.Element("Child1") ?
"attached" : "cloned");
// Compare Child2 identity.
Console.WriteLine("Child2 was {0}",
child2 == xmlTree2.Element("Child2") ?
"attached" : "cloned");
この例では次の出力が生成されます。
Child1 was cloned
Child2 was attached