0

I've created a XPathNodeIterator that contains a few short XML segments (each with a file description):

XPathNodeIterator segments = node.SelectDescendants("Segment", node.NamespaceURI, false);

Now, when trying to loop them, it seems that only the first segment is picked every time. Here are two versions of the loops I've tried (File/Files classes only for example):

while (segments.MoveNext())
{
    File f = GetSingleFileDataFromSegment(segments.Current);

    files.Add(f);
}

Another try:

foreach (XPathNavigator seg in segments)
{
    File f = GetSingleFileDataFromSegment(seg);

    files.Add(f);
}

When viewing a single segment in a loop with Watch or Quickwatch, it looks as it should, all different segments are selected one at a time - but end result is that "files" contain multiple copies of the first segment.

Is this normal behavior with XPathNodeIterator? Or is something missing here? I'm currently using .NET Framework 3.5.

Lauri I
  • 228
  • 1
  • 4
  • 11
  • Can you show a short but complete program that demonstrates the problem, including your XML file? – Jon Skeet Sep 23 '11 at 07:58
  • Would like to, but NDA prevents. – Lauri I Sep 23 '11 at 08:18
  • 1
    An NDA doesn't stop you from writing a separate short but complete program with a separate sample file which demonstrates the same thing. You don't need to reveal any intellectual property here. Of course, it's entirely possible that in working up a short but complete program, you'll work out what's wrong with your real application. – Jon Skeet Sep 23 '11 at 08:22
  • Obliagtory [link to Jon's "Short But Complete Programs" page](http://www.yoda.arachsys.com/csharp/complete.html) – AakashM Sep 23 '11 at 08:42

1 Answers1

0

The problem was in GetSingleFileDataFromSegment -method, which used XPath to get the proper segment. The segment attributes had namespaces in them, and that required the use of a NamespaceManager.

Faulty XPath expression:

f.Location = seg.XPathSelectElement("//*[local-name()='Location']").Value; 

Corrected version:

System.Xml.XmlNamespaceManager nsmanager = new System.Xml.XmlNamespaceManager(seg.ToXmlDocument().NameTable);
nsmanager.AddNamespace("ns", seg.Elements().FirstOrDefault().GetDefaultNamespace().NamespaceName);
f.Location = seg.XPathSelectElement("./ns:Location", nsmanager).Value;

Code above was in the method that received the segment as parameter.

Lauri I
  • 228
  • 1
  • 4
  • 11