LoginSignup
1
2

More than 5 years have passed since last update.

[C#][SQLite][LINQ to XML] DBから取得したデータをXMLで返し、受け取ったXMLを解析する

Last updated at Posted at 2017-12-02

DBに保存されているデータをXML形式で受け取り、
LINQ to XMLの技術を用いて、そのXMLを簡単に解析するためのコードです。
(DB → XML → 解析)

手軽さから、DBはSQLiteを使いました。
なので、nugetでSQLiteのパッケージを導入します。

DBに格納するテスト用のデータは、大阪環状線の駅情報です。
駅データ.jp」で公開している駅情報をそのままDBに保存して使わせて頂きました。

  • DBからデータ取得
  • 取得したデータをXMLに変更
  • そのXMLを解析

1.DBからデータを取得

DBは以下の様な構造です。(stationテーブル)

station_name lon lat
天王寺 135.514124 34.647243
新今宮 135.501076 34.650149
... ... ...
寺田町 135.523437 34.647957

以下のようなクラスを作成しました。

SQLiteIF.css
    public class SQLiteIF
    {
        /// <summary>
        /// 駅情報一覧をXML形式で取得
        /// </summary>
        /// <param name="dbFilePath">.dbファイルのフルパス</param>
        static public string GetStations( string dbFilePath )
        {
            // 取得したレコードをListで保持します。
            // 取得したデータはすべてstring型とする。
            List<Dictionary<string, string>> stationRecords = new List<Dictionary<string, string>>();

            // DBに接続して、クエリを実行する。
            using ( var sqliteConn = new SQLiteConnection( "Data Source=" + dbFilePath ) )
            {
                sqliteConn.Open();
                using ( SQLiteCommand command = sqliteConn.CreateCommand() )
                {
                    // クエリ実行
                    command.CommandText = "SELECT * from station";
                    using ( SQLiteDataReader reader = command.ExecuteReader() )
                    {
                        // 一行一行読み込んでいく
                        while ( reader.Read() )
                        {
                            // Listに追加
                            Dictionary<string, string> record = new Dictionary<string, string>() {
                                { "stationName", reader["station_name"].ToString() },
                                { "longitude", reader["lon"].ToString() },
                                { "latitude",  reader["lat"].ToString()}
                            };
                            stationRecords.Add( record );
                        }
                    }
                }
                sqliteConn.Close();
            }

            // ルート部分のエレメントオブジェクト作成
            XElement rootElement = new XElement( "records" );
            // ルートに対して子のエレメントを追加していく
            foreach ( var record in stationRecords )
            {
                XElement el = new XElement( "record",
                    from keyValue in record
                    select new XElement( keyValue.Key, keyValue.Value )
                    );
                rootElement.Add( el );
            }
            return rootElement.ToString();
        }
    }

取得したレコード情報は、一時的に全てDictionaryに格納しています。

SQLiteIF.css
Dictionary<string, string> record = new Dictionary<string, string>() {
    { "stationName", reader["station_name"].ToString() },
    { "longitude", reader["lon"].ToString() },
    { "latitude",  reader["lat"].ToString()}
};

上記DictionaryをListにAddして、複数のレコード情報を保持しました。

2.取得したデータをXMLに変換

LINQ to XMLを使えば、簡単にXML形式の文字列が作成出来ます。

SQLiteIF.css
// ルート部分のエレメントオブジェクト作成
XElement rootElement = new XElement( "records" );
// ルートに対して子のエレメントを追加していく
foreach ( var record in stationRecords )
{
    XElement el = new XElement( "record",
        from keyValue in record
        select new XElement( keyValue.Key, keyValue.Value )
        );
    rootElement.Add( el );
}
return rootElement.ToString();

LINQのクエリを使うと、簡単にXElementオブジェクトの作成が行えます。
もしかしたら、foreachしなくても一発でXElementオブジェクトが作成出来るかもしれません。
偉い人教えてください……。

XElementオブジェクトさえ出来てしまえば、
後は、ToString()を行うだけでXMLのストリームが作成出来ます。

 <records>
   <record>
     <stationName>天王寺</stationName>
     <longitude>135.514124</longitude>
     <latitude>34.647243</latitude>
   </record>
   <record>
     <stationName>新今宮</stationName>
     <longitude>135.501076</longitude>
     <latitude>34.650149</latitude>
   </record>
   
   ……
   
   <record>
     <stationName>寺田町</stationName>
     <longitude>135.523437</longitude>
     <latitude>34.647957</latitude>
   </record>
 </records>

ちなみにXElementを使うには、以下のusing宣言が必要です。
using System.Xml.Linq;

3.そのXMLを解析

DictionaryからXMLを作成するためにXElementを使用しましたが、
解析する場合もXElementを使用します。

SQLiteIF.css
    class Program
    {
        static void Main( string[] args )
        {
            // XMLストリームを取得
            string xmlStream = SQLiteIF.GetStations( ".dbファイルのフルパスを指定" );

            // XMLストリームからXElementオブジェクトを作成する場合は、
            // LoadではなくParseを使うこと。
            XElement stationsElement = XElement.Parse( xmlStream );

            // <record>要素のコレクションを取得
            IEnumerable<XElement> stations = stationsElement.Elements( "record" );
            // <record>に属している要素から、必要な情報を取得する
            foreach ( var stationElement in stations )
            {
                Console.WriteLine( string.Format( "駅名: {0}", stationElement.Element( "stationName" ).Value ) );
                Console.WriteLine( string.Format( "緯度: {0}", stationElement.Element( "latitude" ).Value ) );
                Console.WriteLine( string.Format( "経度: {0}", stationElement.Element( "longitude" ).Value ) );
                Console.WriteLine();
            }
        }
    }

■ 実行結果

駅名: 天王寺
緯度: 34.647243
経度: 135.514124

駅名: 新今宮
緯度: 34.650149
経度: 135.501076

……

駅名: 寺田町
緯度: 34.647957
経度: 135.523437

関連サイト

1
2
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2