by kirupa |
18 January 2007
In the
previous page, I described how to approach reading an
XML file, and then provided some code and began explaining
what the code does. This page picks up from where we last
left off. - XmlNodeType nodeType = reader.NodeType;
One of the goals we mentioned was to figure out what the
current node actually is. To classify our node, we use the
XmlNodeType class. In the above line, I determine the node
type by accessing our reader obect's
NodeType property and
storing that result in our XmlNodeType object called
nodeType.
- switch (nodeType)
- {
- case XmlNodeType.Element:
- if
(reader.HasAttributes)
- {
- for (int
i =
0; i <
reader.AttributeCount; i++)
- {
- reader.MoveToAttribute(i);
- }
- Console.WriteLine("Attribute is {0} with Value {1}: ", reader.Name, reader.Value);
- }
- break;
- case XmlNodeType.Text:
- Console.WriteLine("Value is: "
+ reader.Value);
- break;
- }
Once I store the node
type in the nodeType object, I use a switch/case statement
to determine whether our node is of type Element or Text.
Switch/case statements are just another way of writing
conditional statements without using if/else statements.
- Console.WriteLine("Element name is {0}", reader.Name);
If our node is an element, I can access the element's name
by calling the Name property from our
reader object. The
element names in our example would be menu,
parent, child,
title, and link.
- if (reader.HasAttributes)
- {
- for (int
i =
0; i <
reader.AttributeCount; i++)
- {
- reader.MoveToAttribute(i);
- }
- Console.WriteLine("Attribute is {0} with Value {1}: ", reader.Name, reader.Value);
- }
As explained in the
intro, some elements may
contain attributes. We check to see if this element
contains an attribute by using the aptly named
HasAttributes property on our reader object.
- if (reader.HasAttributes)
- {
- for (int i = 0; i < reader.AttributeCount; i++)
- {
- reader.MoveToAttribute(i);
- Console.WriteLine("Attribute is {0} with Value {1}: ", reader.Name, reader.Value);
- }
- }
If our element actually
contains attributes, you can use a for loop to navigate
through each attribute. The total number of attributes your
element stores is noted by your reader object's
AttributeCount property. Something really
unique is that it's not good enough to just know the index
position of where your next attribute is. You need to
actually move
to that particular attribute by using the
reader object's
MoveToAttribute property. To
link an earlier analogy I used, you physically move your
magnifying glass to the next node. Once you have moved to the new location, you
can access the Name and Value properties like you did
before.
- case
XmlNodeType.Text:
- Console.WriteLine("Value is: " + reader.Value);
- break;
We reach
the second of our two cases when our element is an xml
node of type Text. When dealing with text content, you don't
have much more work to do. You can simply access the
text value using reader.Value.
While it looked like there was a lot of code, what the code
actually
does is fairly simple. The most important thing to keep in
mind is that the above approach loops through each node in
your code. You cannot, at least in the implementation I
presented, look at a previous or future nude from your
current location. That explains why when you wanted to access the
attribute value, you first had to explicitly move to the next element
before accessing that element's value.
The
code I provided so far is pretty generic. There may be
situations where you want to only access certain elements
from your XML file. The following code highlights how you
can access values from only elements whose names you
specify: - XmlTextReader reader = new XmlTextReader("C:\\links.xml"));
- while (reader.Read())
- {
- XmlNodeType nodeType = reader.NodeType;
- if (nodeType == XmlNodeType.Element)
- {
- switch(reader.Name) {
- case "title":
- Console.WriteLine("TITLE: " + reader.ReadString());
- break;
- case "link":
- Console.WriteLine("LINK: " + reader.ReadString());
- break;
- case "parent":
- reader.MoveToAttribute(0);
- Console.WriteLine("PARENT: " + reader.Value);
- break;
- }
- }
- }
The above code is similar to our earlier
code except my switch/case statement checks for the actual
element name instead of checking whether the node is an
Element or Text. Also, notice that when I am checking for
attributes in the parent element, I am again using the
MoveToAttribute method and
passing in an index number, but since I know exactly how our
XML file is structure, I am bypassing the
for loop and substituting a
value of 0 to our MoveToAttribute
method directly.
Just a final word before we wrap up. If you have a question and/or want to be part of a friendly, collaborative community of over 220k other developers like yourself, post on the forums for a quick response!
|