Here is dummy XPathNavigator implementation I was talking about. Its main
advantage is almost zero memory footprint - it's just an access to parent's
Compile() method implementation.
I wonder if I overlooked any simpler solution (except for no reflection
hacks)? If not I hope V2 API has solved that problem already.
//Safe wrapper to hide dummy XPathNavigator
public class XPathCompiler {
private class DummyXpathNavigator : XPathNavigator {
public override XPathNavigator Clone() {
return new DummyXpathNavigator();
}
public override XPathNodeType NodeType {
get { return XPathNodeType.Root; }
}
public override string LocalName {
get { return String.Empty; }
}
public override string NamespaceURI {
get { return String.Empty; }
}
public override string Name {
get { return String.Empty; }
}
public override string Prefix {
get { return String.Empty; }
}
public override string Value {
get { return String.Empty; }
}
public override string BaseURI {
get { return String.Empty; }
}
public override String XmlLang {
get { return String.Empty; }
}
public override bool IsEmptyElement {
get { return false; }
}
public override XmlNameTable NameTable {
get { return null; }
}
public override bool HasAttributes {
get { return false; }
}
public override string GetAttribute(string localName, string
namespaceURI) {
return string.Empty;
}
public override bool MoveToAttribute(string localName, string
namespaceURI) {
return false;
}
public override bool MoveToFirstAttribute() {
return false;
}
public override bool MoveToNextAttribute() {
return false;
}
public override string GetNamespace(string name) {
return string.Empty;
}
public override bool MoveToNamespace(string name) {
return false;
}
public override bool MoveToFirstNamespace(XPathNamespaceScope
namespaceScope) {
return false;
}
public override bool MoveToNextNamespace(XPathNamespaceScope
namespaceScope) {
return false;
}
public override bool HasChildren {
get { return false; }
}
public override bool MoveToNext() {
return false;
}
public override bool MoveToPrevious() {
return false;
}
public override bool MoveToFirst() {
return false;
}
public override bool MoveToFirstChild() {
return false;
}
public override bool MoveToParent() {
return false;
}
public override void MoveToRoot() {}
public override bool MoveTo( XPathNavigator other ) {
return false;
}
public override bool MoveToId(string id) {
return false;
}
public override bool IsSamePosition(XPathNavigator other) {
return false;
}
public override XPathNodeIterator SelectDescendants(string name,
string namespaceURI, bool matchSelf) {
return null;
}
public override XPathNodeIterator SelectChildren(string name,
string namespaceURI) {
return null;
}
public override XPathNodeIterator SelectChildren(XPathNodeType
nodeType) {
return null;
}
public override XmlNodeOrder ComparePosition( XPathNavigator
navigator ) {
return new XmlNodeOrder();
}
}
//Singleton
private static XPathNavigator _nav = new DummyXpathNavigator();
//Here we go
public static XPathExpression Compile(string xpath) {
return _nav.Compile(xpath);
}
}
And its usage:
XPathDocument doc = new XPathDocument(new StringReader("<foo/>"));
XPathNavigator nav = doc.CreateNavigator();
XPathExpression xe = XPathCompiler.Compile("/foo");
XPathNodeIterator ni = nav.Select(xe);
while (ni.MoveNext()) {
Console.WriteLine(ni.Current.Name);
}
--
Oleg Tkachenko
http://www.tkachenko.com/blog
Multiconn Technologies, Israel