LINQ to XML とは
LINQ to XML は、.NET Framework プログラミング言語から XML を操作できるようにする、LINQ に対応したメモリ内 XML プログラミング インターフェイスです。 … LINQ to XML の最も重要な利点は、統合言語クエリ (LINQ) と統合されていることです。この統合により、メモリ内の XML ドキュメントに対するクエリを記述して、要素および属性のコレクションを取得できます。
LINQ to XMLを使うことで次のようなことができます。
- ファイルまたはストリームからのXMLの読み込み
- ファイルまたはストリームへのXMLのシリアル化
- LINQ to XMLのメソッドを使った、メモリ内のXMLツリー操作
- XMLツリーの新規作成
- LINQを使ったXMLツリーの照会
LINQ to XMLのクラス
LINQ to XMLは、System.Xml.Linq名前空間内のクラスで実現します。各クラスには頭に”X”がついています。代表的なクラスは次のようなものです。
- XElement
- LINQ to XML の基礎クラスの一つで、XMLの要素を表します。このクラスを使用することで、要素の作成、要素のコンテンツの変更、子要素の追加、変更、削除、属性の追加、及び要素コンテンツのテキストへのシリアル化を行えます。
- XAttribute
- XAttributeクラスはXMLの属性を表します。XAttributeはXMLの要素(XElement)に関連付けられている名前と値のペアです。
- XDocument
-
XDocumentクラスは、有効なXMLドキュメントに必要な情報(宣言やコメント)を持つことができます。XDocumentは次の要素を含みます。
- 1つのXDeclaration。これはXML宣言の部分です。
- 1つのXElement。これはXMLドキュメントのルートノードに該当します。
- 任意の数のXProcessingInstruction。これはXML処理命令に該当します。
- 任意の数のXComment。コメントはルート要素の兄弟となりますが、XMLドキュメントはコメントから始めることはできないので、リストの最初の引数にできません。
- DTD用の1つのXDocumentType。XMLドキュメント型定義 (DTD) を表します。
- XNode
-
XNodeは、XMLツリーのノードを表す抽象クラスです。子ノードは格納できません。XNodeからは次のクラスが派生します。
- XText
- XContainer(抽象クラス)
- XComment
- XProcessingInstruction
- XDocumentType
- XContainer
-
XContainerは、子ノード格納できるノードを表す抽象クラスです。次のクラスが派生します。
- XElement
- XDocument
- XText
- テキストノードを表します。
- XComment
- XMLコメントを表します。
- XProcessingInstruction
- XML処理命令を表します。
- XDocumentType
- XMLドキュメント型定義 (DTD) を表します。
XMLの新規作成と保存
各クラスのコンストラクタを組み合わせて1つのXDocumentを作成し、XDocumentのSaveメソッドでファイルに保存してみます。XDocument, XElementのコンストラクタでは指定した名前と要素を持ったXMLを作成しています。
var xdoc = new XDocument(
new XDeclaration("1.0", "utf-8", null)
, new XComment("User情報")
, new XElement(
"Users"
, new XElement(
"User"
, new XAttribute("id", "001")
, new XText("太郎")
)
, new XElement(
"User"
, new XAttribute("id", "002")
, new XText("次郎")
)
, new XElement(
"User"
, new XAttribute("id", "003")
, new XText("三郎")
)
)
);
xdoc.Save(@"user.xml");
user.xml
<?xml version="1.0" encoding="utf-8"?>
<!--User情報-->
<Users>
<User id="001">太郎</User>
<User id="002">次郎</User>
<User id="003">三郎</User>
</Users>
XMLデータの抽出
実際にはXMLファイルを読み込んで操作する機会が多いと思います。上で作ったXMLファイルを操作してみます。LINQ to XMLのメソッドは次のようなものがあります。
メソッド | 内容 |
---|---|
Nodes | すべての子ノード(XNode)を返す。 |
Elements | すべての子要素(XElement)のコレクションをドキュメントの順序で返す。引数でXElementの名前を指定することもできる。 |
Element | 引数で指定した名前の、ドキュメント順序で先頭の子要素(XElement)を返す。 |
Ancestors | 先祖要素(XElement)のコレクションを返す。引数で名前を指定することもできる。 |
Descendants | 子孫要素(XElement)のコレクションを返す。引数で名前を指定することもできる。 |
DescendantNodes | 子孫ルート(XNode)のコレクションを返す。XElement以外も取得できるのがDescendantsとの違い。 |
Root | XMLドキュメントのルート要素です。 |
例えば次のようなHtmlファイルからデータを抽出してみます。
index.html
<!DOCTYPE html>
<html>
<!--html comment-->
<head>
<!--head comment-->
<title>タイトル</title>
</head>
<body>
<!--body comment-->
<p>
<!--p comment-->
Hello World
</p>
</body>
</html>
// ファイルの読み込み
var html = XDocument.Load(@"index.html");
// Bodyタグ要素を取得
var body = html.Root.Element("body");
// pタグ要素を取得
var p = body.Elements("p").First();
// コメントノードをすべて取得
var comments = html.DescendantNodes().OfType<XComment>();
XMLデータの編集
XMLデータを編集するメソッドは次の様な物があります。
これらを一通り使ってみればある程度直観的にXMLを操作できます。
メソッド | 内容 |
---|---|
Add | 指定した内容を子として追加する。 |
AddFirst | 指定した内容を子として、既存の子の内容の先頭に追加する。 |
AddAfterSelf | 現在のノードの直後(同レベル)に指定した内容を追加する。 |
AddBeforeSelf | 現在のノードの直前(同レベル)に指定した内容を追加する。 |
Remove | 現在のノードを親から削除する。 |
RemoveAll | 現在のXElementから子ノード及び属性を削除する。 |
RemoveNodes | 現在のXElement, XDocumentから子ノードを削除する。 |
ReplaceAll | 現在の要素から子ノードを、指定した内容で置き換えます。 |
ReplaceWith | 現在のノードを、指定した内容で置き換えます。 |
SetValue | 現在の要素の値を設定する。 |
SetAttributeValue | 属性の値を設定、属性の追加または削除する。 |
XMLの操作のサンプルを次に示します。
user.xml
<?xml version="1.0" encoding="utf-8"?>
<Users>
<User id="001">
太郎
</User>
<User id="002">
次郎
</User>
<User id="003">
三郎
</User>
</Users>
// XML読み込み
var xdoc = XDocument.Load(@"user.xml");
// Users要素
var users = xdoc.Element("Users");
// id = 003 のユーザー(三郎)を削除
var saburo = users.Elements("User")
.Where(x => x.Attribute("id").Value == "003")
.FirstOrDefault();
saburo.Remove();
// ユーザー要素(花子)を追加
users.Add(new XElement("User", "花子", new XAttribute("id", "101")));
// 修正した内容で保存
xdoc.Save(@"user_update.xml");
コメントを書く