C#によるXML操作の実践ガイド

XMLファイルのプログラムによる生成

C#でXMLファイルを動的に生成する方法を解説します。System.Xml名前空間を使用し、テキストボックスなどのUIコントロールから値を受け取ってXMLを構築します。

using System.Xml;

string filePath = @"C:\data\products.xml";
var settings = new XmlWriterSettings
{
    Indent = true,
    Encoding = Encoding.UTF8
};

using (XmlWriter document = XmlWriter.Create(filePath, settings))
{
    document.WriteStartDocument();
    document.WriteStartElement("製品カタログ");
    
    document.WriteStartElement("製品");
    document.WriteAttributeString("ID", "P001");
    document.WriteElementString("名称", "ノートPC");
    document.WriteElementString("価格", "98000");
    document.WriteEndElement();
    
    document.WriteEndElement();
    document.WriteEndDocument();
}

XMLドキュメントの操作(作成・更新・削除)

以下のような商品XMLを例に各種操作を説明します。

<?xml version="1.0" encoding="utf-8"?>
<商品ストア>
  <商品 分類="電子機器" コード="E1001">
    <タイトル>スマートフォンX</タイトル>
    <メーカー>テック株式会社</メーカー>
    <値段>45000</値段>
  </商品>
</商品ストア>
  1. 新規要素の追加
XmlDocument dataFile = new XmlDocument();
dataFile.Load(@"C:\data\商品ストア.xml");

XmlNode catalog = dataFile.SelectSingleNode("商品ストア");

XmlElement newItem = dataFile.CreateElement("商品");
newItem.SetAttribute("分類", "家庭用品");
newItem.SetAttribute("コード", "H2001");

XmlElement nameElement = dataFile.CreateElement("タイトル");
nameElement.InnerText = "掃除ロボット";
newItem.AppendChild(nameElement);

XmlElement makerElement = dataFile.CreateElement("メーカー");
makerElement.InnerText = "クリーン工業";
newItem.AppendChild(makerElement);

XmlElement priceElement = dataFile.CreateElement("値段");
priceElement.InnerText = "32000";
newItem.AppendChild(priceElement);

catalog.AppendChild(newItem);
dataFile.Save(@"C:\data\商品ストア.xml");
  1. 要素の更新
XmlNodeList productNodes = dataFile.SelectSingleNode("商品ストア").ChildNodes;

foreach (XmlNode item in productNodes)
{
    XmlElement product = (XmlElement)item;
    
    if (product.GetAttribute("分類") == "電子機器")
    {
        product.SetAttribute("分類", "電子デバイス");
        
        XmlNodeList subNodes = product.ChildNodes;
        foreach (XmlNode subItem in subNodes)
        {
            if (subItem.Name == "値段")
            {
                subItem.InnerText = "42000";
                break;
            }
        }
        break;
    }
}

dataFile.Save(@"C:\data\商品ストア.xml");
  1. 要素と属性の削除
XmlNodeList allProducts = dataFile.SelectSingleNode("商品ストア").ChildNodes;

foreach (XmlNode item in allProducts)
{
    XmlElement product = (XmlElement)item;
    
    if (product.GetAttribute("分類") == "電子デバイス")
    {
        product.RemoveAttribute("コード");
    }
    else if (product.GetAttribute("分類") == "家庭用品")
    {
        product.ParentNode.RemoveChild(product);
    }
}

dataFile.Save(@"C:\data\商品ストア.xml");
  1. 全データの表示
XmlNode root = dataFile.SelectSingleNode("商品ストア");
XmlNodeList items = root.ChildNodes;

foreach (XmlNode item in items)
{
    XmlElement product = (XmlElement)item;
    Console.WriteLine($"分類: {product.GetAttribute("分類")}");
    Console.WriteLine($"コード: {product.GetAttribute("コード")}");
    
    foreach (XmlNode detail in product.ChildNodes)
    {
        Console.WriteLine($"{detail.Name}: {detail.InnerText}");
    }
    Console.WriteLine("-------------------");
}

XmlReaderによる効率的なXML読み取り

XmlReaderクラスを使用して、前方参照のみの高速なXML読み取りを実現します。

using System.Xml;

string xmlPath = @"C:\data\inventory.xml";
var config = new XmlReaderSettings
{
    IgnoreWhitespace = true,
    IgnoreComments = true
};

using (XmlReader scanner = XmlReader.Create(xmlPath, config))
{
    while (scanner.Read())
    {
        switch (scanner.NodeType)
        {
            case XmlNodeType.Element:
                Console.WriteLine($"開始要素: {scanner.Name}");
                if (scanner.HasAttributes)
                {
                    for (int i = 0; i < scanner.AttributeCount; i++)
                    {
                        scanner.MoveToAttribute(i);
                        Console.WriteLine($"  属性: {scanner.Name} = {scanner.Value}");
                    }
                    scanner.MoveToElement();
                }
                break;
                
            case XmlNodeType.Text:
                Console.WriteLine($"  テキスト: {scanner.Value}");
                break;
                
            case XmlNodeType.EndElement:
                Console.WriteLine($"終了要素: {scanner.Name}");
                break;
        }
    }
}

LINQ to XMLによるモダンなXML操作

.NET Framework 3.5以降では、LINQ to XMLを使用してより直感的にXMLを操作できます。

using System.Xml.Linq;

XDocument config = XDocument.Load(@"C:\data\settings.xml");

// 新規要素の追加
config.Root.Add(new XElement("セクション",
    new XAttribute("名前", "データベース"),
    new XElement("接続文字列", "Server=localhost;Database=AppDB;"),
    new XElement("タイムアウト", "30")
));

// 条件による要素検索と更新
var dbSection = config.Descendants("セクション")
    .FirstOrDefault(s => s.Attribute("名前")?.Value == "データベース");

if (dbSection != null)
{
    dbSection.Element("タイムアウト").Value = "60";
}

// 特定条件の要素削除
config.Descendants("セクション")
    .Where(s => s.Attribute("名前")?.Value == "旧設定")
    .Remove();

config.Save(@"C:\data\settings.xml");

タグ: C# XML System.Xml LINQ to XML XmlReader

7月5日 00:19 投稿