I’ve been doing some serious work with the XPathNavigator (and running into performance “issues” which has slowed up finishing this), so I went back to re-read the Checklist: XML Performance page. Here’s what they listed for XPath queries:
- Use XPathDocument to process XPath statements.
- Avoid the // operator by reducing the search scope.
- Compile both dynamic and static XPath expressions.
This looks like a very valid list, until you actually try to implement it. Turns out they are mutually exclusive. By implementing #1, it forces you to break #2, since XPathNavigator.Select() always evaluates from the root, not from the context of the current cursor location. XPathNavigator.Select() also makes #3 useless for everything except for queries off the root node, since you normally build XPath statements from the context of the current cursor location (a la XSLT Templates), but Select always evaluates from the root.
Kzu (aka Daniel Cazzulino) pointed out this issue with XPath and XPathNavigator a while ago (prior to being an MVP), and Dare noted that evaluating from the root node context was by design, since the current node context may cause issues with certain ancestor type queries. But kzu replied (and this is my point, too) that this is no different that what happens in XSLT templates. I tried this out in the May VS.Net 2005 CTP, and it still exhibits this behavior.
Can we get an overloaded version of XPathNavigator.Select() and Evaluate() that adds a UseRootContext Boolean flag, so we can turn off this behavior? It can default to the current processing, but when we use the override, switch to the current cursor context. I’ve been messing with the Rotor System.Xml code, trying to figure out the best solution, and so far this is the best I can come up with. I’ve tried to figure out a way to override this behavior with OO techniques, but since most of what needs to be adjusted is internal classes, I can not change the processing without re-writing the XPathDocument from scratch.
Oh, kzu's work around for the context issue can be found here. An excellent read, and definitely something to use until the framework is updated.