オブジェクト階層の XML データへのマップ

メモリに読み込まれた XML ドキュメントは、ツリーという概念で表現されます。 プログラミングでは、オブジェクト階層を利用してツリーのノードにアクセスします。 XML コンテンツがどのようにノードに変換されるかを次の例に示します。

XML が XML ドキュメント オブジェクト モデル (DOM) に読み込まれると、各部がノードに変換されます。これらのノードは、ノード型や値など、ノード自身に関する付加的なメタデータを保持しています。 ノード型はノードのオブジェクトであり、ノード型によって実行可能なアクションおよび設定や取得が可能なプロパティが決まります。

次のような簡単な XML があるとします。

入力

<book>
    <title>The Handmaid's Tale</title>
</book>

この入力は、メモリ上で次のようなノード ツリーとして表現され、ノード型プロパティが割り当てられます。

book と title のノード ツリー表現

サンプル ノード ツリー

book 要素と title 要素は XmlElement になり、要素コンテンツは XmlText オブジェクトになります。 XmlElement のメソッドとプロパティは、XmlText オブジェクトで使用できるメソッドとプロパティとは異なります。 実行可能なアクションはノード型によって決定されるため、XML マークアップがどのノード型になるかを理解することがきわめて重要です。

XML データを読み込み、ノード型に応じて異なるテキストを書き出す例を次に示します。 入力として、次の items.xml という XML データ ファイルを使用します。

入力

<?xml version="1.0"?>
<!-- This is a sample XML document -->
<!DOCTYPE Items [<!ENTITY number "123">]>
<Items>
  <Item>Test with an entity: &number;</Item>
  <Item>test with a child element <more/> stuff</Item>
  <Item>test with a CDATA section <![CDATA[<456>]]> def</Item>
  <Item>Test with a char entity: &#65;</Item>
  <!-- Fourteen chars in this element.-->
  <Item>1234567890ABCD</Item>
</Items>

items.xml ファイルを読み込み、それぞれのノード型の情報を表示するコード サンプルを次に示します。

Imports System
Imports System.IO
Imports System.Xml

Public Class Sample
    Private Const filename As String = "items.xml"

    Public Shared Sub Main()

        Dim reader As XmlTextReader = Nothing

        Try
            ' Load the reader with the data file and 
            'ignore all white space nodes. 
            reader = New XmlTextReader(filename)
            reader.WhitespaceHandling = WhitespaceHandling.None

            ' Parse the file and display each of the nodes.
            While reader.Read()
                Select Case reader.NodeType
                    Case XmlNodeType.Element
                        Console.Write("<{0}>", reader.Name)
                    Case XmlNodeType.Text
                        Console.Write(reader.Value)
                    Case XmlNodeType.CDATA
                        Console.Write("<![CDATA[{0}]]>", reader.Value)
                    Case XmlNodeType.ProcessingInstruction
                        Console.Write("<?{0} {1}?>", reader.Name, reader.Value)
                    Case XmlNodeType.Comment
                        Console.Write("<!--{0}-->", reader.Value)
                    Case XmlNodeType.XmlDeclaration
                        Console.Write("<?xml version='1.0'?>")
                    Case XmlNodeType.Document
                    Case XmlNodeType.DocumentType
                        Console.Write("<!DOCTYPE {0} [{1}]", reader.Name, reader.Value)
                    Case XmlNodeType.EntityReference
                        Console.Write(reader.Name)
                    Case XmlNodeType.EndElement
                        Console.Write("</{0}>", reader.Name)
                End Select
            End While

        Finally
            If Not (reader Is Nothing) Then
                reader.Close()
            End If
        End Try
    End Sub 'Main ' End class
End Class 'Sample
using System;
using System.IO;
using System.Xml;

public class Sample
{
    private const String filename = "items.xml";

    public static void Main()
    {
        XmlTextReader reader = null;

        try
        {
            // Load the reader with the data file and ignore 
            // all white space nodes.
            reader = new XmlTextReader(filename);
            reader.WhitespaceHandling = WhitespaceHandling.None;

            // Parse the file and display each of the nodes.
            while (reader.Read())
            {
                switch (reader.NodeType)
                {
                    case XmlNodeType.Element:
                        Console.Write("<{0}>", reader.Name);
                        break;
                    case XmlNodeType.Text:
                        Console.Write(reader.Value);
                        break;
                    case XmlNodeType.CDATA:
                        Console.Write("<![CDATA[{0}]]>", reader.Value);
                        break;
                    case XmlNodeType.ProcessingInstruction:
                        Console.Write("<?{0} {1}?>", reader.Name, reader.Value);
                        break;
                    case XmlNodeType.Comment:
                        Console.Write("<!--{0}-->", reader.Value);
                        break;
                    case XmlNodeType.XmlDeclaration:
                        Console.Write("<?xml version='1.0'?>");
                        break;
                    case XmlNodeType.Document:
                        break;
                    case XmlNodeType.DocumentType:
                        Console.Write("<!DOCTYPE {0} [{1}]", reader.Name, reader.Value);
                        break;
                    case XmlNodeType.EntityReference:
                        Console.Write(reader.Name);
                        break;
                    case XmlNodeType.EndElement:
                        Console.Write("</{0}>", reader.Name);
                        break;
                }
            }
        }

        finally
        {
            if (reader != null)
                reader.Close();
        }
    }
} // End class

この例の出力を確認すると、データからノード型へのマップがわかります。

出力

<?xml version='1.0'?><!--This is a sample XML document --><!DOCTYPE Items [<!ENTITY number "123">]<Items><Item>Test with an entity: 123</Item><Item>test with a child element <more> stuff</Item><Item>test with a CDATA section <![CDATA[<456>]]> def</Item><Item>Test with a char entity: A</Item><--Fourteen chars in this element.--><Item>1234567890ABCD</Item></Items>

入力と、コードから生成された出力を 1 行ずつ対比させた以下の表を見れば、どのノード テストによってどの出力行が生成されたのかを分析でき、どの XML データがどのノード型になったかがわかります。

入力

出力

ノード型のテスト

<?xml version="1.0"?>

<?xml version='1.0'?>

XmlNodeType.XmlDeclaration

<!-- This is a sample XML document -->

<!-- This is a sample XML document -->

XmlNodeType.Comment

<!DOCTYPE Items [<!ENTITY number "123">]>

<!DOCTYPE Items [<!ENTITY number "123">]

XmlNodeType.DocumentType

<項目>

<項目>

XmlNodeType.Element

<Item>

<項目>

XmlNodeType.Element

Test with an entity: &number;</Item>

Test with an entity: 123

XmlNodeType.Text

</Item>

</Item>

XmlNodeType.EndElement

<項目>

<項目>

XmNodeType.Element

test with a child element

test with a child element

XmlNodeType.Text

<more>

<more>

XmlNodeType.Element

stuff

stuff

XmlNodeType.Text

</Item>

</Item>

XmlNodeType.EndElement

<項目>

<項目>

XmlNodeType.Element

test with a CDATA section

test with a CDATA section

XmlTest.Text

<![CDATA[<456>]]>

<![CDATA[<456>]]>

XmlTest.CDATA

def

def

XmlNodeType.Text

</Item>

</Item>

XmlNodeType.EndElement

<項目>

<項目>

XmlNodeType.Element

Test with a char entity: &#65;

Test with a char entity: A

XmlNodeType.Text

</Item>

</Item>

XmlNodeType.EndElement

<!-- Fourteen chars in this element.-->

<--Fourteen chars in this element.-->

XmlNodeType.Comment

<Item>

<Item>

XmlNodeType.Element

1234567890ABCD

1234567890ABCD

XmlNodeType.Text

</Item>

</Item>

XmlNodeType.EndElement

</Items>

</Items>

XmlNodeType.EndElement

有効なアクションの種類と設定および取得できるプロパティの種類はノード型によって決まるため、割り当てられているノード型を知っておく必要があります。

空白ノードの作成は、データが DOM に読み込まれるときに PreserveWhitespace フラグによって制御されます。 詳細については、「DOM を読み込むときの空白および有意の空白の処理」を参照してください。

DOM に新しいノードを追加するには、「XML ドキュメントへのノードの挿入」を参照してください。 DOM からノードを削除するには、「XML ドキュメントからのノード、コンテンツ、値の削除」を参照してください。 DOM のノードのコンテンツを編集するには、「XML ドキュメントのノード、コンテンツ、値の変更」を参照してください。

参照

概念

XML ドキュメント オブジェクト モデル (DOM)