XMLファイルをパースする (SAXパーサー XmlReaderを利用) - C#
SAXパーサーを用いてXMLファイルをパーシングします。
C#ではSAXパーサーでパーシングする場合はXmlReaderクラスを用います。
コード例
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Xml;
using System.IO;
namespace XMLReaderDemo
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
if (openFileDialog1.ShowDialog() == System.Windows.Forms.DialogResult.OK) {
textBox1.Text = openFileDialog1.FileName;
}
}
private void button2_Click(object sender, EventArgs e)
{
FileStream fs=null;
XmlReader xmlReader=null;
XmlReaderSettings settings =null;
try {
fs = new FileStream(textBox1.Text, FileMode.Open);
settings = new XmlReaderSettings();
settings.IgnoreComments = true;
settings.IgnoreWhitespace = true;
xmlReader = XmlReader.Create(fs, settings);
while (xmlReader.Read() == true) {
XmlNodeType nType = xmlReader.NodeType;
textBox2.Text += "NodeType: " + nType.ToString() + "\r\n";
textBox2.Text += "LocalName: " + xmlReader.LocalName + "\r\n";
textBox2.Text += "Depth: " + Convert.ToString(xmlReader.Depth) + "\r\n";
textBox2.Text += "Name: " + xmlReader.Name + "\r\n";
if (xmlReader.HasValue == true) {
Type valueType = xmlReader.ValueType;
textBox2.Text += "ValueType: " + valueType.ToString() + "\r\n";
textBox2.Text += "Value: " + xmlReader.Value + "\r\n";
}
//属性がある場合
if (xmlReader.HasAttributes == true) {
for (int i=0; i < xmlReader.AttributeCount; i++) {
xmlReader.MoveToAttribute(i);
textBox2.Text += "Attribute Name: " + xmlReader.Name + "\r\n";
if (xmlReader.HasValue == true) {
Type valueType = xmlReader.ValueType;
textBox2.Text += "ValueType: " + valueType.ToString() + "\r\n";
textBox2.Text += "Attribute Value: " + xmlReader.Value + "\r\n";
}
}
xmlReader.MoveToElement();
}
textBox2.Text += "\r\n";
}
}
catch (Exception exc) {
textBox2.Text += "Error: " + exc.Message;
}
finally {
if (fs != null) {
fs.Close();
}
if (xmlReader != null) {
xmlReader.Close();
}
}
}
}
}
解説
XMLファイルを読み込むストリーム(FileStream)を準備します。
fs = new FileStream(textBox1.Text, FileMode.Open);
XmlReaderに渡すオプション(XmlReaderSettings)を作成します。
settings = new XmlReaderSettings();
XmlReaderの設定(XmlReaderSettingsの設定)をします。今回の例ではXMLのコメントとホワイトスペースを無視する設定としました。
settings.IgnoreComments = true;
settings.IgnoreWhitespace = true;
XmlReaderを作成します。newではなくCreate()メソッドを利用します。第一引数にXMLの読み込みストリームを第二引数にXmlReaderSettingsを渡します。
xmlReader = XmlReader.Create(fs, settings);
XmlReaderから読み込みます。Read()メソッドの戻り値がTrueである限り読み続けます。読み込みができなくなるまで(ストリームの末尾にたどり着くまで)読み込み続けます。
while (xmlReader.Read() == true) {
while文の内部は、読み込んだノードの情報をtextBoxに表示するコードです。
次のコードでXMLタグの名称を取得できます。
xmlReader.LocalName
XMLのタグに挟まれた値については
xmlReader.HasValue
プロパティで値があるか判断し、
xmlReader.Value
プロパティで値を取得できます。
タグの属性については
xmlReader.HasAttributes
プロパティで属性のありなしを取得でき
xmlReader.MoveToAttribute()
メソッドでタグ内の属性にアクセスできます。
処理の終了後、finallyブロックでファイルストリームと、XmlReaderをクローズします。
fs.Close();
xmlReader.Close();
実行結果
<?xml version="1.0" encoding="UTF-8"?>
<root>
<node>
<data type="text">データです</data>;
</node>
</root>
NodeType: XmlDeclaration
LocalName: xml
Depth: 0
Name: xml
ValueType: System.String
Value: version="1.0" encoding="UTF-8"
Attribute Name: version
ValueType: System.String
Attribute Value: 1.0
Attribute Name: encoding
ValueType: System.String
Attribute Value: UTF-8
NodeType: Element
LocalName: root
Depth: 0
Name: root
NodeType: Element
LocalName: node
Depth: 1
Name: node
NodeType: Element
LocalName: data
Depth: 2
Name: data
Attribute Name: type
ValueType: System.String
Attribute Value: text
NodeType: Text
LocalName:
Depth: 3
Name:
ValueType: System.String
Value: データです
NodeType: EndElement
LocalName: data
Depth: 2
Name: data
NodeType: EndElement
LocalName: node
Depth: 1
Name: node
NodeType: EndElement
LocalName: root
Depth: 0
Name: root
著者
iPentecのメインプログラマー
C#, ASP.NET の開発がメイン、少し前まではDelphiを愛用