Search code examples
c#xml.net-3.5xmldocumentselectnodes

Behavior of LoadXml and SelectNodes


I have code similar to the first below

String xml1 =
    @"<resultset>
        <result>
            <alamakota />
        </result>
    </resultset>";
String xml2 =
    @"<resultset/>";
XmlDocument xDoc = new XmlDocument();
xDoc.LoadXml(xml1);
XmlNodeList nodes1 = xDoc.SelectNodes("/resultset/result");
xDoc.LoadXml(xml2);
XmlNodeList nodes2 = xDoc.SelectNodes("/resultset/result");
Console.WriteLine(nodes1.Count);
Console.WriteLine(nodes2.Count);

I would expect that WriteLine methods gives 1 and 0 but not always. In normal program run it will give double 0. Also during debug when I put breakpoint on second SelectNodes and check value of nodes1.Count in VS it gives me 1 and 0 at the end. It seems that SelectNodes is evaluated during first check of XmlNodeList and not in line where it is in code, for example code below will give 1 and 0 every time it runs

String xml1 =
    @"<resultset>
        <result>
            <alamakota />
        </result>
    </resultset>";
String xml2 =
    @"<resultset/>";
XmlDocument xDoc = new XmlDocument();
xDoc.LoadXml(xml1);
XmlNodeList nodes1 = xDoc.SelectNodes("/resultset/result");
Int32 c1 = nodes1.Count;
xDoc.LoadXml(xml2);
XmlNodeList nodes2 = xDoc.SelectNodes("/resultset/result");
Console.WriteLine(nodes1.Count);
Console.WriteLine(nodes2.Count);

I know that I can do xDoc = new XmlDocument() after first SelectNodes and it will work like expected but I wonder if this is how it should work because I can't find this scenario at msdn. If yes then why? Please point me to some documentation.


Solution

  • What you are seeing is documented.

    From the documentation from XmlNodeList:

    Changes to the children of the node object that the XmlNodeList collection was created from are immediately reflected in the nodes returned by the XmlNodeList properties and methods.

    And from the documentation for XmlNode.SelectNodes()

    The XmlNodeList object returned by this method will be valid while the underlying document remains unchanged. If the underlying document changes, unexpected results may be returned (no exception will be thrown).

    So, when you overwrite the contents of xDoc with completely new XML, the contents of a previously created XmlNodeList are no longer defined by Microsoft.