Easy XML reading using XmlTextReader

When looking at examples and samples for the .NET System.Xml.XmlTextReader, i was hoping it would be as easy to use as XmlTextWriter. But i did not find such examples. XmlTextReader will read node per node, using the method Read, and a programmer will have to evaluate what type of node the current node is. But XmlTextReader has two short-hand methods: ReadStartElement and ReadElementString. Suppose we have the following xml : [sourcecode lang="xml"] <root> <itemlist> <item> <name>Item1</name> <value>110</value> </item> <item> <name>Item2</name> <value>234</value> </item> <item> <name>Another Item</name> <value>432</value> </item> </itemlist> </root> [/sourcecode] What we want to do is read one item in a simple way. That is possible as follows: [sourcecode lang="csharp"] private void ReadItem(XmlTextReader reader, out String name, out String value) { reader.ReadStartElement("item"); name = reader.ReadElementString("name") ; value = reader.ReadElementString("value"); reader.ReadEndElement(); //item } [/sourcecode] Unfortunately ReadStartElement will throw an exception if the current element is not the same as the wanted element. So we need a bit more code to iterate smartly over all possibilities. [csharp] private void ReadItemList(XmlTextReader reader) { reader.ReadStartElement("itemlist"); reader.Read(); // read next element while (reader.LocalName == "item") { String name; String value; ReadItem(reader, out name, out value) ; // ... do something here with read item ... reader.Read(); } reader.ReadEndElement(); // itemlist } [/csharp] The reader.Read() positions ourself on the next node, allowing some kind of look-ahead, while the ReadEndElement and ReadStartElement can handle this perfectly well. They will either proceed to the next node, or stay on the current node. That's why this code works. For completeness, this does the setup: [csharp] XmlTextReader importReader = new XmlTextReader(fileName); importReader.ReadStartElement("root"); ReadItemList(importReader); importReader.ReadEndElement(); [/csharp] ... where filename points to the file containing the above shown xml. If you have any questions or comments regarding this example, please let me know. This allows for very readable and concise code, but only if you know how the xml file you are reading is formed (the order of the elements). I will solve this in the next post.
Comments
Matt Baker 2017-08-31 15:24:00 UTC

Not sure this works... String listname in ReadItemList is never used.

nathanvda 2017-08-31 15:54:47 UTC

Yes you are right. This code was extracted from a project where we had a lot of different named "itemlists", so the listname was a parameter. I have corrected the code to remove the parameter (as it is not relevant for this example). WTF this is ancient :P :P

Add comment

Recent comments

Tags