yotiky Tech Blog

とあるエンジニアの備忘録

C# - XElement / XDocument の使い方

learn.microsoft.com

learn.microsoft.com

目次

検証環境

  • LINQPad 7
  • .NET 7.0

XElement の使い方

サンプルで扱う PurchaseOrder.xml

<?xml version="1.0"?>
<PurchaseOrder PurchaseOrderNumber="99503" OrderDate="1999-10-20">
    <Address Type="Shipping">
        <Name>Ellen Adams</Name>
        <Street>123 Maple Street</Street>
        <City>Mill Valley</City>
        <State>CA</State>
        <Zip>10999</Zip>
        <Country>USA</Country>
    </Address>
    <Address Type="Billing">
        <Name>Tai Yee</Name>
        <Street>8 Oak Avenue</Street>
        <City>Old Town</City>
        <State>PA</State>
        <Zip>95819</Zip>
        <Country>USA</Country>
    </Address>
    <DeliveryNotes>Please leave packages in shed by driveway.</DeliveryNotes>
    <Items>
        <Item PartNumber="872-AA">
            <ProductName>Lawnmower</ProductName>
            <Quantity>1</Quantity>
            <USPrice>148.95</USPrice>
            <Comment>Confirm this is electric</Comment>
        </Item>
        <Item PartNumber="926-AA">
            <ProductName>Baby Monitor</ProductName>
            <Quantity>2</Quantity>
            <USPrice>39.98</USPrice>
            <ShipDate>1999-05-21</ShipDate>
        </Item>
    </Items>
</PurchaseOrder>

読み込み

// File
var path = Path.Combine(Util.MyQueriesFolder, @"PurchaseOrder.xml");
var doc = XElement.Load(path);
Util.OnDemand("Load File", () => doc).Dump();

var xml = doc.ToString();

// TextReader
using (var sr = new StringReader(xml))
{
    doc = XElement.Load(sr);
    Util.OnDemand("Load TextReader", () => doc).Dump();
}

// XmlReader
using (var sr = new StringReader(xml))
using (var xr = XmlReader.Create(sr))
{
    doc = XElement.Load(xr);
    Util.OnDemand("Load XmlReader", () => doc).Dump();
}

// Stream
using(var memory = new MemoryStream(Encoding.UTF8.GetBytes(xml)))
{
    doc = XElement.Load(memory);
    Util.OnDemand("Load Stream", () => doc).Dump();
}

保存

var srcPath = Path.Combine(Util.MyQueriesFolder, @"PurchaseOrder.xml");
var doc = XElement.Load(srcPath);

// File
var path = Path.Combine(Util.MyQueriesFolder, @"PurchaseOrder_copy.xml");
doc.Save(path);

// TextWriter
using (var sw = new StringWriter())
{
    doc.Save(sw);
    Util.OnDemand("Save TextWriter", () => sw.ToString()).Dump();
}

// XmlWriter
using (var sw = new StringWriter())
using (var xw = XmlWriter.Create(sw))
{
    doc.Save(xw);
    Util.OnDemand("Save XmlWriter", () => sw.ToString()).Dump();
}

// Stream
using (var memory = new MemoryStream())
{
    doc.Save(memory);
    var xml = Encoding.UTF8.GetString(memory.ToArray());
    Util.OnDemand("Save Stream", () => xml).Dump();
}

XDocument の使い方

XML宣言や子要素を1つしか持てないなど、トップノード特有の機能がいくつか存在するが、基本はXElementと同じ。
子要素を取り出す時に、XDocumentの場合は、Rootを1つ挟む必要がある。

var path = Path.Combine(Util.MyQueriesFolder, @"PurchaseOrder.xml");
var xdoc = XDocument.Load(path);
// XML宣言
var dec = xdoc.Declaration;
// Rootプロパティを介してElementsを取得
var docElements = xdoc.Root.Elements();

var xele = XElement.Load(path);
// Rootプロパティは存在しない
var eleElements = xele.Elements();

Util.OnDemand("XDocumentXElement",
    () => Util.VerticalRun(dec, Util.HorizontalRun(true, docElements, eleElements))
).Dump();

XMLツリーの構築

var xdoc = new XDocument(
    new XDeclaration("1.0", "utf-8", "true"),
    new XElement("PurchaseOrder",
        new XAttribute("PurchaseOrderNumber", "99503"),
        new XAttribute("OrderDate", "1999-10-20"),
        new XElement("Address",
            new XAttribute("Type", "Shipping"),
            new XElement("Name", "Ellen Adams"),
            new XElement("Street", "123 Maple Street"),
            new XElement("City", "Mill Valley"),
            new XElement("State", "CA"),
            new XElement("Zip", "10999"),
            new XElement("Country", "USA")
        )
    )
);

Dump ではXML宣言が出ないが、ファイルに保存すると書き出される。