読者です 読者をやめる 読者になる 読者になる

いろいろ備忘録日記

主に .NET と Python絡みのメモを公開しています。

ADO.NET入門記-012 (DataSetにてXMLデータを扱う (DataSet, DataTable, ReadXmlSchema, ReadXml, xsd))

C# ADO.NET

前回の記事 http://d.hatena.ne.jp/gsf_zero1/20070906/p2 にて、データセットXMLデータを流し込むのは
やっているのですが、一応別記事にしました。


DataSetやDataTableにはXMLからデータを取得するメソッドが用意されています。


スキーマを読み込むには以下のメソッドを

ReadXmlSchema(string fileName)

XMLデータを読み込むには以下のメソッドを使用します。

ReadXml(string fileName)


また、XMLスキーマの設定次第では、最初からリレーションを設定済みの状態で
読み込むことができます。設定の仕方は、通常のスキーマの定義の仕方と同じです。


以下、今回使用するXMLスキーマです。
基本的に前回のものと同じですが、リレーションを予め設定してあります。

<?xml version="1.0" encoding="utf-8"?>
<xs:schema 
    id="Memo" 
    targetNamespace="urn:gsf-samples-memo.xsd" 
    elementFormDefault="qualified" 
    xmlns="urn:gsf-samples-memo.xsd" 
    xmlns:mstns="urn:gsf-samples-memo.xsd" 
    xmlns:xs="http://www.w3.org/2001/XMLSchema">

    <xs:element name="Memos">
        <xs:complexType>
            <xs:choice maxOccurs="unbounded">
                <xs:element name="Memo">
                    <xs:complexType>
                        <xs:sequence>
                            <xs:element name="MemoId" type="xs:int" />
                            <xs:element name="Title" type="xs:string" />
                            <xs:element name="Author" type="xs:string" />
                            <xs:element name="Data" type="xs:string" />
                            <xs:element name="CategoryId" type="xs:int" />
                        </xs:sequence>
                    </xs:complexType>
                </xs:element>
                <xs:element name="Category">
                    <xs:complexType>
                        <xs:sequence>
                            <xs:element name="CategoryId" type="xs:int" />
                            <xs:element name="CategoryName" type="xs:string" />
                        </xs:sequence>
                    </xs:complexType>
                </xs:element>
            </xs:choice>
        </xs:complexType>
        <xs:key name="KeyCategory">
            <xs:selector xpath=".//mstns:Category" />
            <xs:field xpath="mstns:CategoryId" />
        </xs:key>
        <xs:keyref name="CategoryMemo" refer="KeyCategory">
            <xs:selector xpath=".//mstns:Memo" />
            <xs:field xpath="mstns:CategoryId" />
        </xs:keyref>
    </xs:element>
</xs:schema>

以下が使用するXMLデータです。
前回のものと同じです。

<?xml version="1.0" encoding="utf-8" ?>
<Memos xmlns="urn:gsf-samples-memo.xsd">
    <Category>
        <CategoryId>1</CategoryId>
        <CategoryName>C#</CategoryName>
    </Category>
    <Category>
        <CategoryId>2</CategoryId>
        <CategoryName>VB2005</CategoryName>
    </Category>
    <Category>
        <CategoryId>3</CategoryId>
        <CategoryName>Java</CategoryName>
    </Category>
    <Memo>
        <MemoId>1</MemoId>
        <Title>タイトル-1</Title>
        <Author>gsf_zero1</Author>
        <Data>メモ-1</Data>
        <CategoryId>1</CategoryId>
    </Memo>
    <Memo>
        <MemoId>2</MemoId>
        <Title>タイトル-2</Title>
        <Author>gsf_zero2</Author>
        <Data>メモ-2</Data>
        <CategoryId>2</CategoryId>
    </Memo>
    <Memo>
        <MemoId>3</MemoId>
        <Title>タイトル-3</Title>
        <Author>gsf_zero3</Author>
        <Data>メモ-3</Data>
        <CategoryId>1</CategoryId>
    </Memo>
    <Memo>
        <MemoId>4</MemoId>
        <Title>タイトル-4</Title>
        <Author>gsf_zero4</Author>
        <Data>メモ-4</Data>
        <CategoryId>3</CategoryId>
    </Memo>
</Memos>


以下、サンプルクラスです。

using System;
using System.Collections.Generic;
using System.Text;

using NUnit.Framework;
using System.Data;

namespace Gsf.Samples.AdoNet {

    [TestFixture()]
    public class AdoNetSample013 {

        [Test()]
        public void XMLデータの読み取りが行なえるかどうかの確認(){
            //
            // XMLからデータの読み取りを行なう.
            //
            DataSet ds = new DataSet();

            ds.ReadXmlSchema("Memo.xsd");
            ds.ReadXml("Memo.xml");

            // 読み込めているかどうかの確認.
            Assert.AreEqual(1,           int.Parse(ds.Tables["Category"].Rows[0]["CategoryId"].ToString()));
            Assert.AreEqual("C#",        ds.Tables["Category"].Rows[0]["CategoryName"].ToString());
            Assert.AreEqual("gsf_zero1", ds.Tables["Memo"].Rows[0]["Author"].ToString());

            // リレーションが設定されているかどうかの確認
            Assert.AreEqual(1,                            ds.Relations.Count);
            Assert.AreEqual("CategoryMemo",               ds.Relations[0].RelationName);
            Assert.AreEqual(typeof(UniqueConstraint),     ds.Tables["Category"].Constraints[0].GetType());
            Assert.AreEqual(typeof(ForeignKeyConstraint), ds.Tables["Memo"].Constraints[0].GetType());

            //
            // データを取得.
            //
            // Memoから属するCategoryを取得する。
            //
            DataTable categoryTable = ds.Tables["Category"];
            DataTable memoTable     = ds.Tables["Memo"];
            foreach(DataRow row in memoTable.Rows) {

                // 所属するカテゴリを取得
                DataRow category = row.GetParentRow("CategoryMemo");

                string displayValue =
                            string.Format(
                                "memo-id:{0}, title:{1}, author:{2}, data:{3}, category:{4}",
                                row["MemoId"],
                                row["Title"],
                                row["Author"],
                                row["Data"],
                                category["CategoryName"]
                            );

                Console.WriteLine(displayValue);
            }

            Console.WriteLine("");

            //
            // データを取得.
            //
            // Categoryから紐付くMemoを取得する。
            //
            foreach(DataRow row in categoryTable.Rows) {
                //
                // 紐付くMemoを取得する.
                //
                foreach(DataRow memoRow in row.GetChildRows("CategoryMemo")) {

                    string displayValue =
                            string.Format(
                                "category-id:{0}, category-name:{1}, memo-id:{2}, memo-data:{3}",
                                row["CategoryId"],
                                row["CategoryName"],
                                memoRow["MemoId"],
                                memoRow["Data"]
                            );

                    Console.WriteLine(displayValue);
                }
            }
        }
    }
}