I’m trying to enumerate all hosts in an XML document, create a db entry for each host, then add each host’s users (also from the XML document) to the db that are tied to that foreign key. The message box in the code below displays each user more times than there are <user> elements. I expected to see “a”, “b” and “c” just twice each, but the code doesn’t seem to stop displaying them.
private void simple_test()
{
var xml =
"<root>
<main>
<host>
<sub>
<user>
<name>
a
</name>
</user>
<user>
<name>
b
</name>
</user>
<user>
<name>
c
</name>
</user>
</sub>
</host>
<host>
<sub>
<user>
<name>
a
</name>
</user>
<user>
<name>
b
</name>
</user>
<user>
<name>
c
</name>
</user>
</sub>
</host>
</main>
</root>";
var xml_reader = XmlReader.Create(new StringReader(xml));
var xpath_doc = new XPathDocument(xml_reader);
var xpath_nav = xpath_doc.CreateNavigator();
XPathExpression expr;
expr = xpath_nav.Compile("//host/*");
var xpni = xpath_nav.Select(expr);
while(xpni.MoveNext())
{
if (xpni.Current == null) continue;
var nav = xpni.Current.Clone();
expr = nav.Compile("//user/*");
var xpni2 = nav.Select(expr);
while (xpni2.MoveNext())
{
if (xpni2.Current == null) continue;
var nav2 = xpni2.Current.Clone();
nav2.SelectSingleNode("//name");
MessageBox.Show(nav2.Value);
}
}
}
As the others have demonstrated, there are more elegant ways to achieve what you need; however, if you’re looking for bugs in your code, here are two.
First:
should presumably be
Second:
This would match any
userelements in your document, and not just descendants of the currentsub. Per the XPath Examples on MSDN://authormatches all<author>elements in the document..//titlematches all<title>elements one or more levels deep in the current context.Thus, if you want to match all
userelements that are descendants of the currentsubat any level, you may use:In your case, since all
userelements are direct children, it would be more efficient to use the following snippet:which is equivalent to:
This avoids unnecessarily traversing the hierarchy looking for deeper-nested elements which don’t exist.
Edit: Removed some incorrect remarks pointed out in the comments.