XmlReader における現在のノードの位置

XmlReader クラスは、XML ストリームまたはファイルへの前方参照専用のアクセスを提供します。現在のノードとは、リーダーが現在位置している XML ノードです。呼び出されたメソッドと実行されたアクションはすべて現在のノードに対して機能し、取得されたすべてのプロパティは現在のノードの値を反映します。

Read メソッドの 1 つを呼び出すと、リーダーの位置は前方へ移動します。ストリームを移動して現在のノード タイプを判定する方法を次の例に示します。

Option Explicit
Option Strict

Imports System
Imports System.IO
Imports System.Xml

Namespace Test
   
   Public Class MyApp
      
      Public Shared Sub Main()
         Dim rdr As New XmlTextReader("books.xml")
         ReadandWrite(rdr)
      End Sub
      
      Public Shared Sub ReadandWrite(rdr As XmlReader)
         'Read each node in the tree.
         While rdr.Read()
            Select Case rdr.NodeType
               Case XmlNodeType.Element
                  Console.Write(("<" & rdr.Name))
                  While rdr.MoveToNextAttribute()
                     Console.Write((" " & rdr.Name & "='" & rdr.Value & "'"))
                  End While
                  Console.Write(">")
                  If rdr.IsEmptyElement = True Then
                     Console.Write("#EmptyElement")
                  Else
                     Console.Write("#Element")
                  End If
               Case XmlNodeType.Text
                  Console.Write(rdr.Value)
                  Console.Write("#Text")
               Case XmlNodeType.CDATA
                  Console.Write(rdr.Value)
               Case XmlNodeType.ProcessingInstruction
                  Console.Write(("<?" & rdr.Name & " " & rdr.Value & "?>"))
               Case XmlNodeType.Comment
                  Console.Write(("<!--" & rdr.Value & "-->"))
               Case XmlNodeType.Document
                  Console.Write("<?xml version='1.0'?>")
               Case XmlNodeType.Whitespace
                  Console.Write(rdr.Value)
               Case XmlNodeType.SignificantWhitespace
                  Console.Write(rdr.Value)
               Case XmlNodeType.EndElement
                  Console.Write(("</" & rdr.Name & ">"))
                  Console.Write("#EndElement")
            End Select
         End While
      End Sub
   End Class
End Namespace
[C#]
using System;
using System.IO;
using System.Xml;
namespace Test
{
   public class MyApp 
   {
     public static void Main()
     {
        XmlTextReader rdr = new XmlTextReader("books.xml");
        ReadandWrite(rdr);
     }
     public static void ReadandWrite(XmlReader rdr)
     {
        //Read each node in the tree.
        while (rdr.Read())
        {
           switch (rdr.NodeType)
           {
             case XmlNodeType.Element:
               Console.Write("<" + rdr.Name);
               while (rdr.MoveToNextAttribute())
                 Console.Write(" " + rdr.Name + "='" + rdr.Value + "'");
                 Console.Write(">");
                 if (rdr.IsEmptyElement == true)
                    Console.Write("#EmptyElement");
                 else
                    Console.Write("#Element");
                 break;
               case XmlNodeType.Text:
                 Console.Write(rdr.Value);
                 Console.Write("#Text");
               break;
               case XmlNodeType.CDATA:
                 Console.Write(rdr.Value);
               break;
               case XmlNodeType.ProcessingInstruction:
                 Console.Write("<?" + rdr.Name + " " + rdr.Value + "?>");
               break;
               case XmlNodeType.Comment:
                 Console.Write("<!--" + rdr.Value + "-->");
               break;
               case XmlNodeType.Document:
                 Console.Write("<?xml version='1.0'?>");
               break;
               case XmlNodeType.Whitespace:
                 Console.Write(rdr.Value);
               break;
               case XmlNodeType.SignificantWhitespace:
                 Console.Write(rdr.Value);
               break;
               case XmlNodeType.EndElement:
                 Console.Write("</" + rdr.Name + ">");
                 Console.Write("#EndElement");
               break;
            }
         }
      }
   }
}

Read を繰り返して呼び出すと次のノードに進みます。通常、これは while ループで実行します。

XmlReader で利用できるプロパティがすべてのノードで利用できるとは限りません。たとえば、現在のノードが要素であり、スラッシュ文字 "/>" で終わっている場合、IsEmptyElementtrue を返します。その他のノード タイプでこのプロパティを呼び出しても、適用できないプロパティであるために false が返されます。属性プロパティと要素プロパティの使用方法を次の例に示します。この例は、要素に属性があるかどうかを確認する方法を示しています。また、要素に属性がある場合に、AttributeCount プロパティを使用して各属性をループで処理する方法も示されています。

Public Sub DisplayAttributes(reader As XmlReader)
    If reader.HasAttributes Then
        Console.WriteLine(("Attributes of <" & reader.Name & ">"))
        Dim i As Integer
        For i = 0 To reader.AttributeCount - 1
            reader.MoveToAttribute(i)
            Console.Write(" {0}={1}", reader.Name, reader.Value)
        Next i
        reader.MoveToElement() 'Moves the reader back to the element node.
    End If
End Sub 'DisplayAttributes
[C#]
public void DisplayAttributes(XmlReader reader)
{
  if (reader.HasAttributes)
  {
    Console.WriteLine("Attributes of <" + reader.Name + ">");
    for (int i = 0; i < reader.AttributeCount; i++)
    {
      reader.MoveToAttribute(i);
      Console.Write(" {0}={1}", reader.Name, reader.Value);
    }
    reader.MoveToElement(); //Moves the reader back to the element node.
  }
}

要素ノードに位置しているときは、MoveToAttribute メソッドを使用して要素の属性リストの中を移動できます。同様に、リーダーが属性ノードに位置しているときに MoveToElement メソッドを呼び出すと、リーダーは現在の属性ノードを所有している要素に移動します。これは、属性間を移動した後で要素へ戻る場合に使われるテクニックです。利用可能なメソッドの完全な一覧については、「XmlReader メンバ」を参照してください。

DTD が含まれる XML ストリームを読み取り、各ノードのプロパティを出力する例を次に示します。この例では、HasAttributes プロパティを使用して、ノードに属性があるかどうかの確認も行います。属性がある場合は、MoveToNextAttribute メソッドを使用して属性名、ローカル名、および名前空間 URI を出力します。

Public Shared Sub Main()
   Dim stream As New StringReader("<!DOCTYPE test [<!ELEMENT test  (item|bar)*><!ELEMENT item (item*)><!ATTLIST item xml:space (default|preserve) #IMPLIED><!ELEMENT bar (#PCDATA|b|i)*><!ELEMENT b (#PCDATA)><!ELEMENT i (#PCDATA)>]> <test> <item> <item xml:space=""preserve"">  <item/>  </item>  </item>  <bar>  <b>This</b>  <i>is</i>  <b>a test</b>  </bar> </test> ")
   Dim myTxtReader As New XmlTextReader(stream)
   Dim myReader As New XmlValidatingReader(myTxtReader)
   myTxtReader.ValidationType = ValidationType.None
   While myReader.Read()
      WriteNodeInfo(myReader)
   End While
End Sub 'Main
 
Private Shared Sub WriteNodeInfo(xmlreader As XmlReader)
   Console.WriteLine("*****************************************************")
   Console.WriteLine()
   Console.WriteLine(("NodeType  = " + xmlreader.NodeType))
   Console.WriteLine(("NodeName  = " + xmlreader.Name))
   Console.WriteLine(("NodeLocalName  = " + xmlreader.LocalName))
   Console.WriteLine(("NodeNamespace  = " + xmlreader.NamespaceURI))
   Console.WriteLine(("NodePrefix  = " + xmlreader.Prefix))
   Console.WriteLine(("NodeHasValue  = " + xmlreader.HasValue))
   Console.WriteLine(("NodeValue = [" + xmlreader.Value + "]"))
   Console.WriteLine(("NodeDepth = " + xmlreader.Depth))
   Console.WriteLine(("IsEmptyElement = " + xmlreader.IsEmptyElement.ToString()))
   Console.WriteLine(("IsDefault = " + xmlreader.IsDefault.ToString()))
   Console.WriteLine(("QuoteChar = " + xmlreader.QuoteChar))
   Console.WriteLine(("XmlSpace = " + xmlreader.XmlSpace))
   Console.WriteLine(("XmlLang = " + xmlreader.XmlLang))
   Console.WriteLine(("AttributeCount = " + xmlreader.AttributeCount))
   Console.WriteLine(("HasAttributes = " + xmlreader.HasAttributes.ToString()))
   Console.WriteLine(("EOF = " + xmlreader.EOF.ToString()))
   Console.WriteLine(("ReadState = " + xmlreader.ReadState.ToString()))
   If xmlreader.HasAttributes Then
      While True = xmlreader.MoveToNextAttribute()
         Console.WriteLine(("AttributeName = " + xmlreader.Name))
         Console.WriteLine(("AttributeLocalName = " + xmlreader.LocalName))
         Console.WriteLine(("AttributeNamespace = " + xmlreader.NamespaceURI))
      End While
   End If
   Console.WriteLine()
   Console.WriteLine("***************************************************")
   Console.WriteLine()
End Sub 'WriteNodeInfo
[C#]
public static void Main() {
    StringReader stream = new StringReader ("<!DOCTYPE test [<!ELEMENT test  (item|bar)*><!ELEMENT item (item*)><!ATTLIST item xml:space (default|preserve) #IMPLIED><!ELEMENT bar (#PCDATA|b|i)*><!ELEMENT b (#PCDATA)><!ELEMENT i (#PCDATA)>]> <test> <item> <item xml:space=\"preserve\">  <item/>  </item>  </item>  <bar>  <b>This</b>  <i>is</i>  <b>a test</b>  </bar> </test> ");
    XmlTextReader myTxtReader = new XmlTextReader (stream);
    XmlValidatingReader myReader = new XmlValidatingReader (myTxtReader);
    myTxtReader.ValidationType = ValidationType.None;
    while (myReader .Read())
        WriteNodeInfo(myReader );
}

private static void WriteNodeInfo(XmlReader xmlreader) {
    Console.WriteLine("*****************************************************");
    Console.WriteLine();
    Console.WriteLine("NodeType  = " + xmlreader.NodeType );            
    Console.WriteLine("NodeName  = " + xmlreader.Name);           
    Console.WriteLine("NodeLocalName  = " + xmlreader.LocalName );            
    Console.WriteLine("NodeNamespace  = " + xmlreader.NamespaceURI);       
    Console.WriteLine("NodePrefix  = " + xmlreader.Prefix);          
    Console.WriteLine("NodeHasValue  = " + xmlreader.HasValue);            
    Console.WriteLine("NodeValue = [" + xmlreader.Value +"]");          
    Console.WriteLine("NodeDepth = " + xmlreader.Depth);          
    Console.WriteLine("IsEmptyElement = " + xmlreader.IsEmptyElement.ToString());  
    Console.WriteLine("IsDefault = " + xmlreader.IsDefault.ToString()); 
    Console.WriteLine("QuoteChar = " + xmlreader.QuoteChar);            
    Console.WriteLine("XmlSpace = " + xmlreader.XmlSpace);           
    Console.WriteLine("XmlLang = " + xmlreader.XmlLang);          
    Console.WriteLine("AttributeCount = " + xmlreader.AttributeCount);
    Console.WriteLine("HasAttributes = " + xmlreader.HasAttributes.ToString());
    Console.WriteLine("EOF = " + xmlreader.EOF.ToString());          
    Console.WriteLine("ReadState = " + xmlreader.ReadState.ToString());            
    if (xmlreader.HasAttributes)
    {
      while (true== xmlreader.MoveToNextAttribute())
      {
         Console.WriteLine("AttributeName = "+ xmlreader.Name);
         Console.WriteLine("AttributeLocalName = "+ xmlreader.LocalName);
         Console.WriteLine("AttributeNamespace = "+ xmlreader.NamespaceURI);
      }
    }
    Console.WriteLine();
    Console.WriteLine("***************************************************");
    Console.WriteLine();
}

最初の 3 つのノードの出力 :

***************************************************

NodeType  = DocumentType
NodeName  = test
NodeLocalName  = test
NodeNamespace  = 
NodePrefix  = 
NodeHasValue  = True
NodeValue = [<!ELEMENT test  (item|bar)*><!ELEMENT item (item*)><!ATTLIST item xml:space (default|preserve) #IMPLIED><!ELEMENT bar (#PCDATA|b|i)*><!ELEMENT b (#PCDATA)><!ELEMENT i (#PCDATA)>]
NodeDepth = 0
IsEmptyElement = False
IsDefault = False
QuoteChar = "
XmlSpace = None
XmlLang = 
AttributeCount = 0
HasAttributes = False
EOF = False
ReadState = Interactive

*************************************************

***************************************************

NodeType  = Whitespace
NodeName  = 
NodeLocalName  = 
NodeNamespace  = 
NodePrefix  = 
NodeHasValue  = True
NodeValue = [ ]
NodeDepth = 0
IsEmptyElement = False
IsDefault = False
QuoteChar = "
XmlSpace = None
XmlLang = 
AttributeCount = 0
HasAttributes = False
EOF = False
ReadState = Interactive

*************************************************

***************************************************

NodeType  = Element
NodeName  = test
NodeLocalName  = test
NodeNamespace  = 
NodePrefix  = 
NodeHasValue  = False
NodeValue = []
NodeDepth = 0
IsEmptyElement = False
IsDefault = False
QuoteChar = "
XmlSpace = None
XmlLang = 
AttributeCount = 0
HasAttributes = False
EOF = False
ReadState = Interactive

*************************************************

すべてのノード タイプの一覧については、「XML ノードの種類」を参照してください。

参照

XmlReader による XML の読み取り | XmlReader のプロパティ設定 | XmlReader と XmlNameTable によるオブジェクトの比較 | XmlReader による属性の読み取り | 要素および属性のコンテンツの読み取り | XmlReader によるコンテンツのスキップ | EntityReference の読み取りと展開 | XmlReader と SAX リーダーの比較 | XmlTextReader による XML データの読み取り | XmlNodeReader によるノード ツリーの読み取り | XmlValidatingReader による XML の検証 | カスタマイズされた XML リーダーの作成 | XmlReader クラス | XmlReader メンバ | XmlNodeReader クラス | XmlNodeReader メンバ | XmlTextReader クラス | XmlTextReader メンバ | XmlValidatingReader クラス | XmlValidatingReader メンバ