[C#] XMLファイルをパースする (DOMパーサー XmlDocumentを利用)
このページのタグ:[C#] [XML] [DOM]
DOMパーサーを用いてXMLファイルをパーシングします。
C#ではDOMパーサーでパーシングする場合はXmlDocumentクラスを用います。
※XPathを使うとよりシンプルにパーシング処理を記述できます。XPathを使ったXmlDocumentの操作方法はこちらの記事で紹介しています。

概要

DOMを用いてXMLファイルをパー寝具するにはXmlDocumentオブジェクトを作成し、Load()メソッドを用いてXMLファイルを読み込みます。パーシングされた結果の木構造がDocumentElementをルートノードとして格納されます。DocumentElementから子ノードをたどって各要素にアクセスします。

コード例


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;

namespace XMLDocumentDemo
{
  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)
    {
      XmlDocument xmlDocument = new XmlDocument();
      xmlDocument.Load(textBox1.Text);

      XmlElement elem = xmlDocument.DocumentElement;
      textBox2.Text += "NodeType; " + elem.NodeType.ToString() + "\r\n";
      textBox2.Text += "LocalName; " + elem.LocalName + "\r\n";
      textBox2.Text += "Name; " + elem.Name + "\r\n";
      textBox2.Text += "\r\n";

      if (elem.HasChildNodes == true) {
        XmlNode childNode = elem.FirstChild;

        while (childNode != null) {
          textBox2.Text += "NodeType; " + childNode.NodeType.ToString() + "\r\n";
          textBox2.Text += "LocalName; " + childNode.LocalName + "\r\n";
          textBox2.Text += "Name; " + childNode.Name + "\r\n";
          textBox2.Text += "\r\n";

          if (childNode.HasChildNodes == true) {
            for (int i=0; i < childNode.ChildNodes.Count; i++) {
              XmlNode dataNode= childNode.ChildNodes[i];

              textBox2.Text += "NodeType; " + dataNode.NodeType.ToString() + "\r\n";
              textBox2.Text += "LocalName; " + dataNode.LocalName + "\r\n";
              textBox2.Text += "Name; " + dataNode.Name + "\r\n";
              for (int j=0; j < dataNode.Attributes.Count; j++) {
                XmlAttribute xmlAttr = dataNode.Attributes[j];
                textBox2.Text += "LocalName; " + xmlAttr.LocalName + "\r\n";
                textBox2.Text += "Name; " + xmlAttr.Name + "\r\n";
                textBox2.Text += "Value; " + xmlAttr.Value + "\r\n";
              }
              textBox2.Text += "\r\n";
               
              if (dataNode.HasChildNodes == true) {
                XmlNode valueNode = dataNode.ChildNodes[0];
                textBox2.Text += "NodeType; " + valueNode.NodeType.ToString() + "\r\n";
                textBox2.Text += "LocalName; " + valueNode.LocalName + "\r\n";
                textBox2.Text += "Name; " + valueNode.LocalName + "\r\n";
                textBox2.Text += "Value; " + valueNode.Value + "\r\n";
                textBox2.Text += "\r\n";
              }

              textBox2.Text += "\r\n";
            }
          }
          childNode = childNode.NextSibling;
        }
      }
    }
  }
}

解説

XmlDocument xmlDocument = new XmlDocument();
にてXmlDocumentの宣言とインスタンスの作成をします。

xmlDocument.Load(textBox1.Text);
にて、Load()メソッドでXMLファイルを読み込みます。

XmlElement elem = xmlDocument.DocumentElement;
XmlDocumentのルートノードのにはxmlDocument.DocumentElementプロパティでアクセスできます。

textBox2.Text += "NodeType; " + elem.NodeType.ToString() + "\r\n";
textBox2.Text += "LocalName; " + elem.LocalName + "\r\n";
textBox2.Text += "Name; " + elem.Name + "\r\n";
textBox2.Text += "\r\n";
ルートノードの内容をtextBox2に表示しします。今回はNodeType, LocalName, Nameの値をテキストボックスに表示します。

if (elem.HasChildNodes == true) {
ルートノードに子ノードがある場合は、子ノードを読み込みます。
XmlNode childNode = elem.FirstChild;
FirstChildプロパティを用いることで最初の子ノードにアクセスできます。

textBox2.Text += "NodeType; " + childNode.NodeType.ToString() + "\r\n";
textBox2.Text += "LocalName; " + childNode.LocalName + "\r\n";
textBox2.Text += "Name; " + childNode.Name + "\r\n";
textBox2.Text += "\r\n";
子ノードのタグ名をtextBox2に表示します。

if (childNode.HasChildNodes == true) {
ノードがさらに子ノードを持っているか確認します。

for (int i=0; i < childNode.ChildNodes.Count; i++) {
  XmlNode dataNode= childNode.ChildNodes[i];
子ノードがあれば、子ノードの個数分だけループします。ループ内でi番目の子ノードを取得します。

textBox2.Text += "NodeType; " + dataNode.NodeType.ToString() + "\r\n";
textBox2.Text += "LocalName; " + dataNode.LocalName + "\r\n";
textBox2.Text += "Name; " + dataNode.Name + "\r\n";
取得したノードのタグ名をtextBox2に表示します。

for (int j=0; j < dataNode.Attributes.Count; j++) {
  XmlAttribute xmlAttr = dataNode.Attributes[j];
  textBox2.Text += "LocalName; " + xmlAttr.LocalName + "\r\n";
  textBox2.Text += "Name; " + xmlAttr.Name + "\r\n";
  textBox2.Text += "Value; " + xmlAttr.Value + "\r\n";
}
にて、ノードの属性を取得し属性の名前と値をtextBox2に表示します。

if (dataNode.HasChildNodes == true) {
  XmlNode valueNode = dataNode.ChildNodes[0];
  textBox2.Text += "NodeType; " + valueNode.NodeType.ToString() + "\r\n";
  textBox2.Text += "LocalName; " + valueNode.LocalName + "\r\n";
  textBox2.Text += "Name; " + valueNode.LocalName + "\r\n";
  textBox2.Text += "Value; " + valueNode.Value + "\r\n";
  textBox2.Text += "\r\n";
}
さらに子ノードがあるか確認し、子ノードがあれば、そのタグ名と値をtextBox2に表示します。

childNode = childNode.NextSibling;
にて、次の兄弟ノードを選択します。この処理をすべての兄弟ノードについて繰り返しています。

実行結果

入力データ (XMLファイル)


<?xml version="1.0" encoding="UTF-8"?> 
<root> 
  <node>
    <data type="text">データ1です</data> 
  </node>
  <node> 
    <data type="text">データ2です</data> 
  </node>
  <node>
    <data type="text">データ3です</data> 
  </node>
</root>

実行結果


NodeType; Element
LocalName; root
Name; root

NodeType; Element
LocalName; node
Name; node

NodeType; Element
LocalName; data
Name; data
LocalName; type
Name; type
Value; text

NodeType; Text
LocalName; #text
Name; #text
Value; データ1です


NodeType; Element
LocalName; node
Name; node

NodeType; Element
LocalName; data
Name; data
LocalName; type
Name; type
Value; text

NodeType; Text
LocalName; #text
Name; #text
Value; データ2です


NodeType; Element
LocalName; node
Name; node

NodeType; Element
LocalName; data
Name; data
LocalName; type
Name; type
Value; text

NodeType; Text
LocalName; #text
Name; #text
Value; データ3です

プライバシー    iPentecについて
iPentec all rights reserverd. (ISDC)