Without going into the gory details of why I had a need for this, here's a C# code snippet for iterative tree traversal of elements in an XML document using XPathNavigator that takes advantage of parent pointers.
[ download source ]test.xml
1 <?xml version="1.0" encoding="UTF-8" standalone="no" ?>
2 <test>
3 <a/>
4 <b/>
5 <c>
6 <c1/>
7 <c2>
8 <c2i/>
9 <c2ii/>
10 </c2>
11 </c>
12 </test>
test.cs
1 using System;
2 using System.Xml.XPath;
3
4 public class IterativeTraversal
5 {
6
7 public static void Main()
8 {
9
10 XPathDocument doc = new XPathDocument("test.xml");
11 XPathNavigator nav = doc.CreateNavigator();
12 nav.MoveToFollowing(XPathNodeType.Element); /* skip xml decl */
13 XPathNavigator startPosition = nav.Clone();
14
15 bool leaf = false;
16 bool searching = false;
17
18 do
19 {
20 leaf = true;
21 if (nav.HasChildren)
22 {
23 nav.MoveToFirstChild();
24 if (nav.NodeType == XPathNodeType.Element)
25 {
26 leaf = false;
27 nav.MoveToParent();
28
29 /* begin processing interior node */
30 Console.WriteLine(nav.Name);
31 /* end processing interior node */
32
33 nav.MoveToFirstChild();
34 }
35 else
36 {
37 /* parent was a leaf element, this child was not*/
38 nav.MoveToParent();
39 }
40 }
41
42 if (leaf)
43 {
44 /* begin processing leaf node */
45 Console.WriteLine(nav.Name);
46 /* end processing leaf node */
47
48 if (!nav.MoveToNext(XPathNodeType.Element))
49 {
50 do
51 {
52 searching = false;
53 nav.MoveToParent();
54 if ((!nav.IsSamePosition(startPosition)) &&
55 (!nav.NodeType.Equals(XPathNodeType.Root)))
56 {
57 if (!nav.MoveToNext(XPathNodeType.Element))
58 {
59 /* no next sibling, search for parent's next sibling */
60 searching = true;
61 }
62 }
63 } while (searching && !nav.IsSamePosition(startPosition) && !nav.NodeType.Equals(XPathNodeType.Root));
64 }
65 }
66 } while (!nav.IsSamePosition(startPosition) && !nav.NodeType.Equals(XPathNodeType.Root));
67
68 }
69 }