CSVファイルをXMLファイルに変換する その2(C#)

C#

CSVファイルをXMLファイルに変換する(C#)でCSVファイルをXMLにするサンプルコードを作成しましたが、今度はCSVをXML化し、適切なタグ名をつけたXMLに整形するコードになります。

・CSVデータ

1,ユーザ1,20,2000/01/01,1
2,ユーザ2,21,2000/02/01,1
3,ユーザ3,22,2000/03/01,1
4,ユーザ4,23,2000/04/01,1
5,ユーザ5,24,2000/05/01,2
6,ユーザ6,25,2000/06/01,2
7,ユーザ7,26,2000/07/01,2

・結果出力したいXMLデータ

<?xml version="1.0" encoding="shift_jis"?>
<user_list>
  <user>
    <id>1</id>
    <name>ユーザ1</name>
    <age>20</age>
    <birthdate>2000.01.01</birthdate>
    <gender>M</gender>
  </user>
・・・(省略)
  <user>
    <id>7</id>
    <name>ユーザ7</name>
    <age>26</age>
    <birthdate>2000.07.01</birthdate>
    <gender>F</gender>
  </user>
</user_list>

CSV→XML→XMLの変換サンプル

            //csvファイルを読み込みxmlにする
            XDocument doc = new XDocument(new XElement("csv"));
            using (var parser = new TextFieldParser("input.csv"))
            {
                parser.Delimiters = new string[] { "," };
                while (!parser.EndOfData)
                {
                    XElement elmrow = new XElement("row");

                    var row = parser.ReadFields();

                    for (int i = 0; i < row.Length; i++)
                    {
                        XElement elmfield = new XElement("field", new XAttribute("index", (i + 1)), row[i]);
                        elmrow.Add(elmfield);
                    }
                    doc.Root.Add(elmrow);
                }
            }

            //xsltファイルを読み込む
            XslCompiledTransform xslt = new XslCompiledTransform();
            xslt.Load("xml2xml.xslt");

            XDocument xdoc_result = new XDocument(new XDeclaration("1.0", "shift-jis", ""));
            //xmlをxsltで変換する
            using (XmlWriter writer = xdoc_result.CreateWriter())
            {
                xslt.Transform(doc.CreateReader(), writer);
            }
            //変換した結果のxmlを出力する
            xdoc_result.Save("output.xml");

説明と処理結果

CSVファイルをXMLファイルに変換する(C#)と同様に、csvファイルをxmlファイルに変換します。

変換したXMLにXSLTで変換を掛け、タグ名等を直し整形したXMLに作り直します。
XML→XMLの変換については、XMLを別のXMLに変換する(C#)をご参照ください。

・input.csv
例としてid, ユーザ名, 年齢, 生年月日, 性別(1:男,2:女) を想定したデータを作成します。

1,ユーザ1,20,2000/01/01,1
2,ユーザ2,21,2000/02/01,1
3,ユーザ3,22,2000/03/01,1
4,ユーザ4,23,2000/04/01,1
5,ユーザ5,24,2000/05/01,2
6,ユーザ6,25,2000/06/01,2
7,ユーザ7,26,2000/07/01,2

・input.csv を xml化したデータ
今回はファイルとして出力しませんが、XDocument docには以下のようなデータとして入ります。

<csv>
  <row>
    <field index="1">1</field>
    <field index="2">ユーザ1</field>
    <field index="3">20</field>
    <field index="4">2000/01/01</field>
    <field index="5">1</field>
  </row>
・・・(省略)
  <row>
    <field index="1">7</field>
    <field index="2">ユーザ7</field>
    <field index="3">26</field>
    <field index="4">2000/07/01</field>
    <field index="5">2</field>
  </row>
</csv>

・xml2xml.xslt
csvから作成したXMLを別のXMLに変換するためのxsltファイルは以下のようにしています。
今回は、値をそのまま入れるのではなく、性別(1,2)を(M,F)に条件文を使用し変換しています。
生年月日を’yyyy/MM/dd’から’yyyy.MM.dd’にするため、’/’→’.’に置換しています。

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
	<xsl:template match="csv">
		<user_list>
			<xsl:apply-templates select="row"/>
		</user_list>
	</xsl:template>
	<xsl:template match="row">
		<user>
			<id>
				<xsl:value-of select="field[@index='1']"/>
			</id>
			<name>
				<xsl:value-of select="field[@index='2']"/>
			</name>
			<age>
				<xsl:value-of select="field[@index='3']"/>
			</age>
			<birthdate>
				<xsl:value-of select="translate(field[@index='4'],'/','.')"/>
			</birthdate>
			<gender>
				<xsl:variable name="gnd" select="field[@index='5']"/>
				<xsl:choose>
					<xsl:when test="$gnd=1">M</xsl:when>
					<xsl:when test="$gnd=2">F</xsl:when>
				</xsl:choose>
			</gender>
		</user>
	</xsl:template>
</xsl:stylesheet>

・output.xml
変換した結果のXMLは以下のように出力されます。

<?xml version="1.0" encoding="shift_jis"?>
<user_list>
  <user>
    <id>1</id>
    <name>ユーザ1</name>
    <age>20</age>
    <birthdate>2000.01.01</birthdate>
    <gender>M</gender>
  </user>
・・・(省略)
  <user>
    <id>7</id>
    <name>ユーザ7</name>
    <age>26</age>
    <birthdate>2000.07.01</birthdate>
    <gender>F</gender>
  </user>
</user_list>

csvデータ項目の追加や、出力するxmlファイルのタグ名の変更、構造の変更をしたい場合でも、
C#のコードの変更をせずにxsltファイルの変更のみで対応が可能です。
またデータの変換定義をxsltに集約しているので機能的な切り分けもされ、評価もし易いです。

いざデータ連携のテストを行うと細かな調整が必要になるケースが多々あるため、このような実装にしておくと簡単に現場で調整等が効きます。

xsltの書き方や使用できる関数等は別でまとめてみようと思います。

コメント

タイトルとURLをコピーしました