Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Is it possible to write an XPath function that returns a nodeset?

26 views
Skip to first unread message

Mike Schilling

unread,
Oct 13, 2002, 2:26:36 PM10/13/02
to
I suspect the answer is no; I hope I'm wrong, since being able to do so is
crucial to the application I'm trying to move to .NET.

I've done the following:

1. Create a subclass of XPathNodeIterator that returns a single
XPathNavigator.

2. Created an implementation of IXsltContextFunction which returns
XPathResultType.NodeSet from ReturnType(). Its
Invoke returns an instance of the class from item 1.

3. Created a subclass of XsltContext. In its ResolveFunction, if it sees
the URI and local name of my extension function, it returns a new instance
of the function in item 2.

4. Write a test program to create an XPathExpression, set its context to the
class in item 3, and evaluate the expression.

This works up to a point. My function does get called, does create the
iterator successfully, and does return it. Unfortunately, then the
following exception gets thrown:

System.Xml.Xsl.XsltException: Function 'ap:ctx-document()' has failed. --->
System.NotSupportedException: XPath+SingleNodeIterator is an unsupported
type.
at System.Xml.XPath.XsltFunction.InvokeFunction(XPathNavigator qy)
--- End of inner exception stack trace ---
at System.Xml.XPath.XsltFunction.InvokeFunction(XPathNavigator qy)
at System.Xml.XPath.XsltFunction.setContext(XPathNavigator context)
at System.Xml.XPath.BaseAxisQuery.setContext(XPathNavigator e)
at System.Xml.XPath.BaseAxisQuery.setContext(XPathNavigator e)
at System.Xml.XPath.MethodOperand.getValue(XPathNavigator qyContext,
XPathNodeIterator iterator)
at System.Xml.XPath.XPathNavigator.Evaluate(XPathExpression expr,
XPathNodeIterator context)
at System.Xml.XPath.XPathNavigator.Evaluate(XPathExpression expr)

By looking at System.Xml.XPath.XsltFunction.InvokeFunction, I think I see
the problem. It isn't sufficient for the return value from the function to
be an XPathNodeIterator; it has to be a subclass of
System.Xml.XPath.ResetableIterator. This is an internal class in the
SystemXML assembly, making it impossible for user code to subclass. This
seems to lead to the impossibility of what I want to do.


I also experimented with have the function's return type be Navigator
instead of NodeSet. This does appear to successfully return an
XPathNavigator, but that's useless in more complex XPath expressions e.g.
trying to get count(function(...)) throws an exception, since count expects
a node set.

Hopefully, I'm missing something, and someone can tell me what is is.

Mike


Prajakta Joshi

unread,
Oct 14, 2002, 3:12:59 PM10/14/02
to
Hi Mike,

Unfortunately in the current design of XPath classes, it is not possible to
return a subclassed XPathNodeIterator from XPath function. This issue will
be addressed in next version.

Currently, there is a workaround using XSLT. If you are writing a function
that returns a custom XPathNodeIterator inside a stylesheet, you can assign
the value of your function to a RTF variable and create a nodeset over it
using msxsl:node-set() function.

If you want to use only XPath, it might get tricker and the workaround
depends on your function. One option is to use
XmlDocument.CreateNavigator() within your function.

HTH,
Prajakta

--------------------
| From: "Mike Schilling" <mscotts...@hotmail.com>
| Newsgroups:
microsoft.public.dotnet.languages.csharp,microsoft.public.dotnet.framework,m
icrosoft.public.dotnet.xml
| Subject: Is it possible to write an XPath function that returns a nodeset?
| Lines: 57
| X-Priority: 3
| X-MSMail-Priority: Normal
| X-Newsreader: Microsoft Outlook Express 6.00.2600.0000
| X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2600.0000
| Message-ID: <wViq9.3287$wF1.23...@newssvr21.news.prodigy.com>
| NNTP-Posting-Host: 64.171.255.33
| X-Complaints-To: ab...@prodigy.net
| X-Trace: newssvr21.news.prodigy.com 1034533596 ST000 64.171.255.33 (Sun,
13 Oct 2002 14:26:36 EDT)
| NNTP-Posting-Date: Sun, 13 Oct 2002 14:26:36 EDT
| Organization: Prodigy Internet http://www.prodigy.com
| X-UserInfo1:
FKPO@MC@OHUUSWHXGBH\_RLARJT@QDDMEPWXODMMHXMTWA]EP]RAQFW[ML\THRCKV^GGZKJMGV^^
_JSCFFUA_QXFGVSCYRPILH]TRVKC^LSN@DX_HCAFX__@J\DAJBVMY\ZWZCZLPA^MVH_P@\\EOMW\
YSXHG__IJQY_@M[A[[AXQ_XDSTAR]\PG]NVAQUVM
| Date: Sun, 13 Oct 2002 18:26:36 GMT
| Path:
cpmsftngxa06!tkmsftngp01!newsfeed00.sul.t-online.de!t-online.de!skynet.be!sk
ynet.be!news-out.cwix.com!newsfeed.cwix.com!prodigy.com!newsmst01.news.prodi
gy.com!prodigy.com!postmaster.news.prodigy.com!newssvr21.news.prodigy.com.PO
STED!2da89474!not-for-mail
| Xref: cpmsftngxa06 microsoft.public.dotnet.framework:27659
microsoft.public.dotnet.xml:8829
microsoft.public.dotnet.languages.csharp:99550
| X-Tomcat-NG: microsoft.public.dotnet.xml

0 new messages