
C# でスマートに XML を操る!読み込みから書き出しまで完全ガイド
システム開発において、設定ファイルやデータ連携の形式として XML (Extensible Markup Language) を扱う場面は少なくありません。C# では、.NET Framework に標準搭載されている機能を利用することで、XML ファイルの読み込みや書き出しを簡単に行うことができます。
このブログでは、C# で XML ファイルを効率的に扱うための基本的な方法から、具体的なコード例、そして注意点までを分かりやすく解説します。これを読めば、あなたも C# で XML を自由自在に操れるようになるでしょう!
XML 読み込みの基本:XmlDocument クラス
C# で XML ファイルを読み込む最も基本的な方法は、System.Xml 名前空間にある XmlDocument クラスを使用することです。
手順:
System.Xml名前空間を using ディレクティブで追加します。XmlDocumentクラスのインスタンスを作成します。XmlDocumentオブジェクトのLoad()メソッドに XML ファイルのパスを指定して XML ファイルを読み込みます。
基本的なコード例:
using System.Xml;
public class XmlReaderExample
{
public static void ReadXmlFile(string filePath)
{
XmlDocument xmlDoc = new XmlDocument();
try
{
xmlDoc.Load(filePath);
Console.WriteLine("XML ファイルの読み込みに成功しました。");
// ここで XML ドキュメントを操作する処理を記述します
}
catch (XmlException ex)
{
Console.WriteLine($"XML ファイルの読み込み中にエラーが発生しました: {ex.Message}");
}
catch (System.IO.FileNotFoundException)
{
Console.WriteLine($"指定されたファイルが見つかりませんでした: {filePath}");
}
}
public static void Main(string[] args)
{
string xmlFilePath = "sample.xml"; // 読み込む XML ファイルのパス
ReadXmlFile(xmlFilePath);
}
}
XML ドキュメントの操作:
XmlDocument オブジェクトが XML ファイルの内容をメモリ上に読み込んだら、様々なプロパティやメソッドを使って XML ドキュメントを操作できます。
- ルート要素の取得:
xmlDoc.DocumentElementプロパティ - ノードのリストを取得:
xmlDoc.GetElementsByTagName("タグ名")メソッド - ノードの属性を取得:
XmlNode.Attributes["属性名"].Value
具体的なノードへのアクセス例:
// ルート要素を取得
XmlElement rootElement = xmlDoc.DocumentElement;
Console.WriteLine($"ルート要素名: {rootElement.Name}");
// 特定のタグ名の要素をすべて取得
XmlNodeList bookList = xmlDoc.GetElementsByTagName("book");
Console.WriteLine($"見つかった book 要素の数: {bookList.Count}");
// 各 book 要素を処理
foreach (XmlNode bookNode in bookList)
{
// title 要素の値を取得
XmlNode titleNode = bookNode.SelectSingleNode("title");
if (titleNode != null)
{
Console.WriteLine($"書籍タイトル: {titleNode.InnerText}");
}
// price 属性の値を取得
if (bookNode.Attributes["price"] != null)
{
Console.WriteLine($"価格: {bookNode.Attributes["price"].Value}");
}
}
XML 出力の基本:XmlWriter クラス
C# で XML ファイルを出力するには、XmlWriter クラスを使用するのが一般的です。XmlWriter は、XML ドキュメントをストリームに出力するための機能を提供します。
手順:
XmlWriterSettingsクラスを使用して、出力形式などの設定を行います(インデント、エンコーディングなど)。XmlWriter.Create()メソッドにファイルパスと設定オブジェクトを指定してXmlWriterのインスタンスを作成します。XmlWriterオブジェクトのメソッド (WriteStartDocument(),WriteStartElement(),WriteAttributeString(),WriteString(),WriteEndElement(),WriteEndDocument()) を使用して XML ドキュメントを記述します。- 最後に、
XmlWriterオブジェクトのClose()メソッドを呼び出してストリームを閉じ、ファイルを保存します。
基本的なコード例:
using System.Xml;
public class XmlWriterExample
{
public static void WriteXmlFile(string filePath)
{
XmlWriterSettings settings = new XmlWriterSettings();
settings.Indent = true; // インデントを設定して見やすくする
settings.Encoding = System.Text.Encoding.UTF8; // エンコーディングを設定
using (XmlWriter writer = XmlWriter.Create(filePath, settings))
{
writer.WriteStartDocument(); // XML ドキュメントの開始
writer.WriteStartElement("bookstore"); // ルート要素の開始
writer.WriteStartElement("book"); // book 要素の開始
writer.WriteAttributeString("price", "2980"); // price 属性の追加
writer.WriteStartElement("title"); // title 要素の開始
writer.WriteString("C# XML プログラミング"); // title 要素の値
writer.WriteEndElement(); // title 要素の終了
writer.WriteStartElement("author"); // author 要素の開始
writer.WriteString("山田 太郎"); // author 要素の値
writer.WriteEndElement(); // author 要素の終了
writer.WriteEndElement(); // book 要素の終了
writer.WriteStartElement("book"); // 別の book 要素
writer.WriteAttributeString("price", "3500");
writer.WriteStartElement("title");
writer.WriteString("はじめての XML");
writer.WriteEndElement();
writer.WriteStartElement("author");
writer.WriteString("鈴木 一郎");
writer.WriteEndElement();
writer.WriteEndElement(); // book 要素の終了
writer.WriteEndElement(); // bookstore 要素の終了
writer.WriteEndDocument(); // XML ドキュメントの終了
}
Console.WriteLine($"XML ファイルが {filePath} に書き出されました。");
}
public static void Main(string[] args)
{
string xmlFilePath = "output.xml"; // 出力する XML ファイルのパス
WriteXmlFile(xmlFilePath);
}
}
より簡潔な XML 操作:LINQ to XML
.NET Framework 3.5 以降では、LINQ to XML を使用することで、XML の読み込み、書き出し、操作をより簡潔な構文で行うことができます。
using System.Xml.Linq;
using System.Linq;
public class LinqToXmlReaderExample
{
public static void ReadXmlFileLinq(string filePath)
{
try
{
XDocument xmlDoc = XDocument.Load(filePath);
Console.WriteLine("XML ファイルの読み込みに成功しました (LINQ to XML)。");
// ルート要素名を取得
XElement rootElement = xmlDoc.Root;
Console.WriteLine($"ルート要素名: {rootElement.Name}");
// book 要素をすべて取得し、タイトルと価格を表示
var books = from book in xmlDoc.Descendants("book")
select new
{
Title = book.Element("title")?.Value,
Price = (string)book.Attribute("price")
};
foreach (var book in books)
{
Console.WriteLine($"書籍タイトル: {book.Title}, 価格: {book.Price}");
}
}
catch (System.IO.FileNotFoundException)
{
Console.WriteLine($"指定されたファイルが見つかりませんでした: {filePath}");
}
catch (XmlException ex)
{
Console.WriteLine($"XML ファイルの読み込み中にエラーが発生しました (LINQ to XML): {ex.Message}");
}
}
public static void Main(string[] args)
{
string xmlFilePath = "sample.xml";
ReadXmlFileLinq(xmlFilePath);
}
}
using System.Xml.Linq;
public class LinqToXmlWriterExample
{
public static void WriteXmlFileLinq(string filePath)
{
XDocument xmlDoc = new XDocument(
new XDeclaration("1.0", "utf-8", "yes"), // XML 宣言
new XElement("bookstore", // ルート要素
new XElement("book", new XAttribute("price", "3200"),
new XElement("title", "LINQ to XML 入門"),
new XElement("author", "田中 一郎")
),
new XElement("book", new XAttribute("price", "2800"),
new XElement("title", "XML の基礎"),
new XElement("author", "高橋 さゆり")
)
)
);
try
{
xmlDoc.Save(filePath);
Console.WriteLine($"XML ファイルが {filePath} に書き出されました (LINQ to XML)。");
}
catch (Exception ex)
{
Console.WriteLine($"XML ファイルの書き出し中にエラーが発生しました (LINQ to XML): {ex.Message}");
}
}
public static void Main(string[] args)
{
string xmlFilePath = "output_linq.xml";
WriteXmlFileLinq(xmlFilePath);
}
}
LINQ to XML を使用すると、XML ドキュメントの構造をオブジェクトとして扱い、より直感的で簡潔なコードで XML の操作を行うことができます。
POCO クラスを使った XML の読み書き
XML のデータを直接 XML ドキュメントとして操作するだけでなく、C# のクラス(POCO クラス)と XML を相互に変換することで、よりオブジェクト指向的なプログラミングが可能になります。これには、System.Xml.Serialization 名前空間にある XmlSerializer クラスを使用します。
1. POCO クラスの定義
まず、XML の構造に対応した C# のクラスを定義します。XML の要素や属性は、クラスのプロパティとして定義します。XmlRootAttribute でルート要素名を指定したり、XmlElementAttribute や XmlAttributeAttribute で要素や属性へのマッピングを制御したりできます。
例:書籍 (Book) クラスと書籍リスト (Bookstore) クラス
using System.Collections.Generic;
using System.Xml.Serialization;
[XmlRoot("bookstore")]
public class Bookstore
{
[XmlElement("book")]
public List Books { get; set; }
}
public class Book
{
[XmlElement("title")]
public string Title { get; set; }
[XmlElement("author")]
public string Author { get; set; }
[XmlAttribute("price")]
public decimal Price { get; set; }
}
2. XML ファイルの読み込み (POCO クラスへのデシリアライズ)
XmlSerializer クラスの Deserialize() メソッドを使用すると、XML ファイルの内容を POCO クラスのインスタンスに変換(デシリアライズ)できます。
コード例:
using System.IO;
using System.Xml.Serialization;
public class XmlDeserializeExample
{
public static Bookstore ReadXmlAsObject(string filePath)
{
XmlSerializer serializer = new XmlSerializer(typeof(Bookstore));
try
{
using (FileStream fs = new FileStream(filePath, FileMode.Open))
{
Bookstore bookstore = (Bookstore)serializer.Deserialize(fs);
Console.WriteLine("XML ファイルのデシリアライズに成功しました。");
return bookstore;
}
}
catch (System.IO.FileNotFoundException)
{
Console.WriteLine($"指定されたファイルが見つかりませんでした: {filePath}");
return null;
}
catch (System.Xml.XmlException ex)
{
Console.WriteLine($"XML ファイルの形式が不正です: {ex.Message}");
return null;
}
}
public static void Main(string[] args)
{
string xmlFilePath = "books.xml"; // デシリアライズする XML ファイル
Bookstore bookstore = ReadXmlAsObject(xmlFilePath);
if (bookstore != null && bookstore.Books != null)
{
foreach (Book book in bookstore.Books)
{
Console.WriteLine($"タイトル: {book.Title}, 著者: {book.Author}, 価格: {book.Price}");
}
}
}
}
books.xml の例:
<?xml version="1.0" encoding="utf-8"?> <bookstore> <book price="2980"> <title>C# XML プログラミング</title> <author>山田 太郎</author> </book> <book price="3500"> <title>はじめての XML</title> <author>鈴木 一郎</author> </book> </bookstore>
3. XML ファイルの書き出し (POCO クラスからのシリアライズ)
XmlSerializer クラスの Serialize() メソッドを使用すると、POCO クラスのインスタンスの内容を XML ファイルに書き出し(シリアライズ)できます。
コード例:
using System.Collections.Generic;
using System.IO;
using System.Xml.Serialization;
public class XmlSerializeExample
{
public static void WriteObjectAsXml(string filePath, Bookstore bookstore)
{
XmlSerializer serializer = new XmlSerializer(typeof(Bookstore));
XmlWriterSettings settings = new XmlWriterSettings();
settings.Indent = true;
settings.Encoding = System.Text.Encoding.UTF8;
try
{
using (XmlWriter writer = XmlWriter.Create(filePath, settings))
{
serializer.Serialize(writer, bookstore);
Console.WriteLine($"Bookstore オブジェクトが {filePath} に XML としてシリアライズされました。");
}
}
catch (Exception ex)
{
Console.WriteLine($"XML ファイルのシリアライズ中にエラーが発生しました: {ex.Message}");
}
}
public static void Main(string[] args)
{
string xmlFilePath = "output_books.xml"; // シリアライズ先の XML ファイル
Bookstore bookstore = new Bookstore
{
Books = new List
{
new Book { Title = "C# オブジェクト指向", Author = "佐藤 二郎", Price = 3800 },
new Book { Title = "XML データ処理", Author = "田中 三郎", Price = 3200 }
}
};
WriteObjectAsXml(xmlFilePath, bookstore);
}
}
output_books.xml の内容例:
<?xml version="1.0" encoding="utf-8"?> <bookstore xmlns:xsi="[http://www.w3.org/2001/XMLSchema-instance](http://www.w3.org/2001/XMLSchema-instance)" xmlns:xsd="[http://www.w3.org/2001/XMLSchema](http://www.w3.org/2001/XMLSchema)"> <book price="3800"> <title>C# オブジェクト指向</title> <author>佐藤 二郎</author> </book> <book price="3200"> <title>XML データ処理</title> <author>田中 三郎</author> </book> </bookstore>
注意点
- 例外処理: XML ファイルの読み込みや書き出し時には、ファイルが見つからない、XML の形式が不正であるなどの例外が発生する可能性があります。必ず
try-catchブロックで例外処理を行うようにしましょう。 - エンコーディング: XML ファイルのエンコーディングと C# アプリケーションのエンコーディングが一致していることを確認してください。
XmlWriterSettingsでエンコーディングを指定できます。 - 大きな XML ファイル: 非常に大きな XML ファイルを
XmlDocumentで読み込むと、メモリを大量に消費する可能性があります。そのような場合は、XmlReaderクラスを使用してストリームとして順次読み込むことを検討してください。
まとめ
C# で XML を扱う方法はいくつかありますが、POCO クラスと XmlSerializer を組み合わせることで、XML のデータをより自然な C# のオブジェクトとして扱うことができます。これにより、XML データの操作がより直感的になり、コードの保守性も向上します。
XML の構造が明確な場合は、ぜひこの POCO クラスを使った方法を検討してみてください。