In Visual Studio 2003, if you wanted to return a node set from managed code to XSLT using an XSLT extension function, you had to use a hack invented by Oleg Tkachenko (see http://msdn.microsoft.com/library/en-us/dnexxml/html/xml05192003.asp, If At First You Don't Succeed section). Visual Studio 2005 corrects the situation that made the hack necessary, but now the hack no longer works!
To return a node set to XSLT from managed code, you need to create a class derived from the abstract class XPathNodeIterator. For example:
Imports System.Xml
Imports System.Xml.XPath
Imports System.Collections.Generic
Public Class XPathNodeIteratorImplementation
Inherits XPathNodeIterator
Dim items As List(Of XPathNavigator) = New List(Of XPathNavigator)
Dim _currentPosition As Integer = 0
Public Overrides ReadOnly Property CurrentPosition() As Integer
Get
Return _currentPosition
End Get
End Property
Public Overrides ReadOnly Property Current() As XPathNavigator
Get
Return items(CurrentPosition)
End Get
End Property
Public Sub Add(ByVal item As XPathNavigator)
items.Add(item)
End Sub
Public Overrides Function Clone() As XPathNodeIterator
Dim clonedItem As XPathNodeIteratorImplementation = New XPathNodeIteratorImplementation
For Each item As XPathNavigator In items
clonedItem.Add(item)
Next
clonedItem.Reset()
Return clonedItem
End Function
Public Sub Reset()
_currentPosition = 0
End Sub
Public Overrides Function MoveNext() As Boolean
If _currentPosition >= items.Count Then Return False
_currentPosition += 1
If CurrentPosition >= items.Count Then Return False
Return True
End Function
Public Overrides ReadOnly Property Count() As Integer
Get
Return items.Count
End Get
End Property
End Class
This class can be returned to XSLT from an extension function. Thus, instead of creating an ArrayList of XPathNavigator objects and casting it to a XPathNodeIterator object, simply add the XPathNavigator objects to an instance of XPathNodeIteratorImplementation and return that to XSLT.