Current Node Position in XmlReader
The XmlReader class provides forward-only access to an XML stream or file. The current node is the XML node on which the reader is currently positioned, and all methods called and actions taken are in relation to that current node, and all properties retrieved reflect the value of the current node.
The reader is advanced by calls to one of the Read methods. The following example shows how you navigate through the stream to determine the current node type.
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;
}
}
}
}
}
Calling Read repeatedly moves to the next node, and is typically performed inside a while loop.
The properties available in XmlReader are not available on every node type. For example, the IsEmptyElement returns true if the current node is an element and ends with a forward slash character "/>". Calling this property on any other node type returns false, as this property is not applicable to other node types. The following example shows the use of attribute and element properties. It shows how to check if an element has attributes. If the element has an attribute, the example shows how to loop through the attributes using the AttributeCount property.
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.
}
}
When positioned on an element node, the MoveToAttribute methods allow you to navigate through the attribute list of the element. Similarly, when the reader is positioned on an attribute node, a call to the MoveToElement method positions the reader at the element that owns the current attribute node. This is the technique that is used to move back to the element after navigating through its attributes. For a complete list of available methods, see XmlReader Members.
The following example reads an XML stream with a DTD and prints node properties for each node. The example also checks if the node has an attribute by using the HasAttributes property. If there are attributes, the code uses the MoveToNextAttribute method and prints out the attribute name, local name, and namespace 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();
}
Output for the first three nodes:
***************************************************
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
*************************************************
For a list of all the node types, see Types of XML Nodes.
See Also
Reading XML with the XmlReader | Property Settings on XmlReader | Object Comparison Using XmlNameTable with XmlReader | Reading Attributes with XmlReader | Reading Element and Attributes Content | Skipping Content with XmlReader | EntityReference Reading and Expansion | Comparing XmlReader to SAX Reader | Reading XML Data with XmlTextReader | Reading Node Trees with XmlNodeReader | Validating XML with XmlValidatingReader | Customized XML Reader Creation | XmlReader Class | XmlReader Members | XmlNodeReader Class | XmlNodeReader Members | XmlTextReader Class | XmlTextReader Members | XmlValidatingReader Class | XmlValidatingReader