On implementing custom XsltContext when extending XPath

| 6 Comments | 1 TrackBack
Here is another easy-to-solve-when-you-know-what-is-wrong problem. It took me couple of hours to find the solution, so I wanna share it. Hope it'll be useful to anybody.

The problem. When adding custom XPath extension functions as described in "HOW TO: Implement and Use Custom Extension Functions When You Execute XPath Queries in Visual C# .NET" KB article and "Adding Custom Functions to XPath" article at MSDN Extreme XML column you can find that any XPath expressions having namespace prefixes, like "/foo:bar" just can't be evaluated due to nasty System.ArgumentNullException deeply in the XPath engine.

The reason. It turned out that internal XPath classes, e.g. BaseAxisQuery expect custom XsltContext implementation to resolve namespaces prefixes (XsltContext extends XmlNamespaceManager) with respect to the NameTable, just as internal default XsltContext implementation - UndefinedXsltContext class does. The documentaion unfortunately omits that point and sample implementation in the above articles too.

The solution. Just override LookupNamespace(string prefix) method in your XsltContext implementation and pass given prefix through the NameTable:

public override string LookupNamespace(string prefix) {
    if (prefix == String.Empty)
        return String.Empty;
    string uri = base.LookupNamespace(NameTable.Get(prefix));
    if (uri == null)
        throw new XsltException("Undeclared namespace prefix - " + 
              prefix, null);
    return uri;
Easy, ain't it? I'm stupid spent two hours to get it.

Related Blog Posts

1 TrackBack

TrackBack URL: http://www.tkachenko.com/cgi-bin/mt-tb.cgi/44

In my previous post, I mentioned that the only changes are prefacing your XPath function with a namespace prefix. However, thanks to a post from Oleg Tkachenko, I found a way around this. In the CustomContext class, override LookupNamespace(string pref... Read More


Thank you very much.

Thank you *so* much! I was going nuts!

Thank you very much. I was getting very angry with this problem. You saved my soul :-)

Haha, awesome work dude, that just saved my ass

I think u just saved me 2 hours (probably more). Thanks

Thanks Oleg, that one had me stumped as well, until I saw your solution.

Leave a comment