I have a big (~40mb) collection of XML data, split in many files which are not well formed, so i merge them, add a root node and load all the xml in a XmlDocument. Its basically a list of 3 different types which can be nested in a few different ways. This example should show most of the cases:
<Root>
<A>
<A>
<A></A>
<A></A>
</A>
</A>
<A />
<B>
<A>
<A>
<A></A>
<A></A>
</A>
</A>
</B>
<C />
</Root>
Im separating all A, B and C nodes by using XPath expressions on a XmlDocument (//A, //B, //C), convert the resulting nodesets to a datatable and show a list of all nodes of each nodetype separately in a Datagridview. This works fine.
But now Im facing an even bigger file and as soon as i load it, it shows me only 4 rows. Then i added a breakpoint at the line where the actual XmlDocument.SelectNodes happens and checked the resulting NodeSet. It shows me about 25,000 entries. After continuing the program loaded and whoops, all my 25k rows were shown. I tried it again and i can reproduce it. If i step over XmlDocument.SelectNodes by hand, it works. If i dont break there, it does not. Im not spawning a single thread in my application.
How can i debug this any further? What to look for? I have experienced such behaviour with multithreaded libraries such as jsch (ssh) but im dont see why this should happen in my case.
Thank you very much!
// class XmlToDataTable:
private DataTable CreateTable(NamedXPath logType,
List<XmlColumn> columns,
ITableCreator tableCreator)
{
// I have to break here -->
XmlNodeList xmlNodeList = logFile.GetEntries(logType);
// <-- I have to break here
DataTable dataTable = tableCreator.CreateTableLayout(columns);
foreach (XmlNode xmlNode in xmlNodeList)
{
DataRow row = dataTable.NewRow();
tableCreator.PopulateRow(xmlNode, row, columns);
dataTable.Rows.Add(row);
}
return dataTable;
}
// class Logfile:
public XmlNodeList GetEntries(NamedXPath e)
{
return (_xmlDocument != null && _xmlDocument.HasChildNodes)
? _xmlDocument.SelectNodes(e.XPath)
: new XmlNullObjectNodeList();
}
// _xmlDocument gets loaded here after reading all xml fragments into a string
// (ugly, i know. the // ugly! comment reminds me about that ;))
private void CreateXmlDoc()
{
_xmlDocument = new XmlDocument();
_xmlDocument.LoadXml(OPEN_ROOT_ELEMENT + _xmlString +
CLOSE_ROOT_ELEMENT);
if (DataChanged != null)
DataChanged(this, new EventArgs());
}
// class NamedXPath:
public abstract class NamedXPath
{
private readonly String _name;
private readonly String _xPath;
protected NamedXPath(string name, string xPath)
{
_name = name;
_xPath = xPath;
}
public string Name
{
get { return _name; }
}
public string XPath
{
get { return _xPath; }
}
}