Search code examples
c#.netxmlreader

How to work reliably with XmlReader


I'm using the XmlReader class, the forward-only reader. A method I'm calling moves the cursor as a side-effect. However, sometimes the method throws an exception, and leaves the cursor somewhere unexpected. How can I handle that?

xml.ReadStartElement("root");

if (xml.IsStartElement("Results"))
{
    try
    {
        results = Results.FromXml(xml);
        // if method successful, it reads past the closing tag of the 'Results' element
    }
    catch
    {
        results = null;
        // I want to manually move the cursor past the closing tag of the 'Results' element.
    }
}

Example document

<root>
    <results>
        <arbitaryxml/>
    </results>*
    <signatures>

If the Results.FromXml method is successful, the cursor gets left at *. However if it fails, it might be left anywhere inside the results element. I want my catch block to make sure the cursor is advanced to *. (NB. The next element isn't always called 'signatures').

I found this quite hard to explain. Please ask if it needs clarification, I can give more examples.


Solution

  • Jim is right, the ReadSubtree method works, although it's a tad fiddly:

    if (xml.IsStartElement("Results"))
    {
        // Be careful so that the cursor will be left after the closing tag of the 'Results' element, even if Results.FromXml throws.
    
        using (XmlReader resultsElement = xml.ReadSubtree())
        {
            resultsElement.Read();
            try 
            {
                results = Results.FromXml(resultsElement);
            }
            catch (Exception e)
            {
                Console.Error.WriteLine("Reading results xml went wrong {0}", e.Message);
            }
        }
    
        xml.ReadEndElement();
    }