Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using XmlReader how do I restart at the beginning?

Tags:

c#

xml

This is really a 2 part question...

  1. I have a XmlReader object I have created from a memory stream. I have used the .Read() method a few times and now I want to go back to the beginning and start over at the declaration node. How can I do that?

  2. When creating the XmlReader object I create a XmlDocument object and a MemoryStream object. Do these objects need to be destroyed somehow after creating the XmlReader with the memory stream? Or would destroying them also effect the XmlReader object?

This is how I create the XmlReader object

XmlReader xmlReader = null;
XmlDocument doc = new XmlDocument();
doc.Load(m_sXMLPath);

if (doc.FirstChild.NodeType == XmlNodeType.XmlDeclaration)
{
    XmlDeclaration dec = null;
    byte[] bytes = null;
    MemoryStream ms = null;

    dec = (XmlDeclaration)doc.FirstChild;
    switch (dec.Encoding.ToLower())
    {
        case "utf-8":
            bytes = Encoding.UTF8.GetBytes(File.ReadAllText(m_sXMLPath));
            break;
        case "utf-16":
            bytes = Encoding.Unicode.GetBytes(File.ReadAllText(m_sXMLPath));
            break;
        default:
            throw new XmlException("");
    }

    if (bytes != null)
    {
        ms = new MemoryStream(bytes);
        xmlReader = XmlReader.Create(ms);
    }
}
like image 477
Arvo Bowen Avatar asked Oct 10 '13 17:10

Arvo Bowen


2 Answers

You cannot restart your XmlReader object to the beginning. As per Microsoft's documentation:

XmlReader provides forward-only, read-only access to a stream of XML data. The XmlReader class conforms to the W3C Extensible Markup Language (XML) 1.0 and the Namespaces in XML recommendations. http://msdn.microsoft.com/en-us/library/System.Xml.XmlReader.aspx

If for some reason you really do need to go back to the beginning, instead you should use your XmlReader to load a XDocument object. You can then use the XDocument object to query any part of your XML. In addition, you should wrap your Stream based objects in a using block so you don't need to worry about destruction. Example below:

XDocument myXmlDoc;
using(MemoryStream ms = new MemoryStream(bytes))
{
     using(XmlReader xmlReader = XmlReader.Create(ms))
     {
           myXmlDoc = XDocument.Load(xmlReader);

           //query your XDocument here to your heart's desire here in any order you want
      }
 }

In case you aren't familar with LINQ to XML take a look at the documentation here

If you don't want to use XDocument and stick to XmlDocument you can also use that (without queries) to re-traverse your XML document. Either way though you do not need to dispose of a XmlDocument (or XDocument) when you are done with it since it's not a disposable object.

like image 191
JNYRanger Avatar answered Oct 06 '22 17:10

JNYRanger


The way you're using XmlReader makes no sense. Once you have the data loaded into the XmlDocument (XDocument would be better), there's no sense in using an XmlReader.

In .NET, it is not generally necessary to destroy objects after use - that's what the garbage collector is for.

like image 21
John Saunders Avatar answered Oct 06 '22 18:10

John Saunders