Microsoft KB Archive/324899

From BetaArchive Wiki

Article ID: 324899

Article Last Modified on 9/29/2006



APPLIES TO

  • Microsoft Visual Basic .NET 2003 Standard Edition
  • Microsoft Visual Basic .NET 2002 Standard Edition
  • Microsoft .NET Framework 1.0
  • Microsoft .NET Framework 1.1



This article was previously published under Q324899

SUMMARY

Non-standard user-defined functions that are used in XPath query expressions are referred to as XPath extension functions. You might want to implement a custom XPath extension function when the standard XPath functions do not address a specific requirement. The Microsoft .NET Framework provides interfaces that you can use to implement and to use custom extension functions and user-defined variables in XPath expressions that are used to execute XPath queries in .NET applications. The XsltContext class, the IXsltContextFunction interface, and the IXsltContextVariable interface are all implemented in the System.Xml.Xsl namespace and are the .NET Framework components that you use to address this requirement.

This step-by-step article explains the use of these interfaces and provides a code sample to illustrate their application in implementing and using extension functions and user-defined variables in XPath expressions.

back to the top

Role of XsltContext

The .NET Framework XPath processor (implemented by the XPathNavigator class in the System.Xml.XPath namespace) uses an XsltContext object to resolve references to unknown functions and variables that it finds in XPath query expressions. You must implement and associate a custom XsltContext object with the XPathNavigator object that is used to execute XPath queries to resolve references to user-defined extension functions and variables in the query expressions. The XsltContext class, the IXsltContextFunction interface, and the IXsltContextVariable interface are the .NET Framework components that you use to implement such a custom execution context. These components are implemented in the System.Xml.Xsl namespace. They are the API elements that constitute the core interface between the .NET Framework XPath and XSLT processors when resolving references to user-defined extension functions and variables in XPath query expressions that are used in XSLT style sheets.

Microsoft recommends that you use XSLT extension objects and inline script blocks to implement user-defined extension functions that are referenced in XPath query expressions that are used in XSLT style sheets. For additional information about implementing and using XSLT extension objects, click the article number below to view the article in the Microsoft Knowledge Base:

321702 HOW TO: Use Extension Objects When You Execute XSL Transformations in Visual Basic .NET Applications


Microsoft recommends that you implement a custom XsltContext to resolve references to user-defined extension functions and variables in XPath query expressions only when you programmatically execute XPath queries in .NET applications by using an XPathNavigator object. A custom XsltContext class can be implemented by inheriting from the XsltContext abstract base class that is implemented in the System.Xml.Xsl namespace. An object instance of the custom XsltContext class can then be used to encapsulate the execution context of the XPath processor and resolve references to user-defined extension functions and variables in XPath query expressions.

ResolveFunction and ResolveVariable are the two key methods of the XsltContext abstract base class that you must override to implement the custom resolution functionality. These methods of the custom XsltContext are called by the XPath processor at run time to resolve references to user-defined extension functions and variables in XPath query expressions. The ResolveFunction method must be implemented to return a custom IXsltContextFunction object that can be used by the XPath processor to resolve references to user-defined extension functions. The ResolveVariable method must be implemented to return a custom IXsltContextVariable object that can be used by the XPath processor to resolve references to user-defined variables.

back to the top

Role of IXsltContextFunction

An IXsltContextFunction object is used by the XPath processor at run time to resolve references to user-defined functions in XPath query expressions. This is an object instance of a custom class that implements the IXsltContextFunction interface that is defined in the System.Xml.Xsl namespace.

The user-defined functions that are used in an XPath query expression must be implemented by the custom IXsltContextFunction object that is used by the XPath processor to resolve references to extension functions. The instance of the custom IXsltContextFunction object to use must be returned by the ResolveFunction method of the custom XsltContext that is associated with the XPath processor.

At run time, the Invoke method of the custom IXsltContextFunction object that is supplied by the custom XsltContext is executed to resolve references to extension functions in XPath query expressions.

back to the top

Role of IXsltContextVariable

An IXsltContextVariable object is used by the XPath processor at run time to resolve references to user-defined variables in XPath query expressions. This is an object instance of a custom class that implements the IXsltContextVariable interface that is implemented in the System.Xml.Xsl namespace.

The instance of the custom IXsltContextVariable object to use must be returned by the ResolveVariable method of the custom XsltContext that is associated with the XPath processor.

The Evaluate method of the IXsltContextVariable object that is supplied by the custom XsltContext is executed to resolve references to user-defined variables in XPath query expressions.

back to the top

Resolve User-defined Extension Functions and Variables (Process Flow Diagram)

The following is a process flow diagram that depicts the use of custom XsltContext, IXsltContextFunction, and IXsltContextVariable objects in the resolution of user-defined extension functions and variables that are found in an XPath query expression. In this illustration, the EvaluateXPathNavigator method is used to execute an XPath query whose expression references a user-defined extension function and a user-defined variable.

The key points to bear in mind are the following:

  • A custom XsltContext must be implemented and associated with the XPath processor to resolve references to user-defined extension functions and variables in XPath expressions.
  • The ResolveFunction method of the custom XsltContext is executed to resolve a reference to a user-defined extension function. This method returns an object instance of a custom IXsltContextFunction class that implements the extension function. The Invoke method of the returned IXsltContextFunction object is executed by the XPath processor to resolve and execute the function.
  • The ResolveVariable method of the custom XsltContext is executed to resolve a reference to a user-defined variable. This method returns an object instance of a custom IXsltContextVariable class whose Evaluate method is executed by the XPath processor to access the value of the variable.

back to the top

Create the Sample .NET Application

This section describes how to set up a sample Visual Basic .NET Console Application project that illustrates the process of implementing and using custom XsltContext, IXsltContextFunction, and IXsltContextVariable classes to resolve references to extension functions and user-defined variables in XPath query expressions.

To create the sample application, follow these steps:

  1. In Visual Studio .NET, create a new Visual Basic .NET Console Application project named XPathExtensionFunctions.
  2. Use the following XML to create and add an XML document named Books.xml to the project. The XPath queries in the sample application access the data in this document:

    <?xml version="1.0" encoding="utf-8" ?> 
    <Books>
        <Title>A Brief History of Time</Title>
        <Title>Principle Of Relativity</Title>
    </Books>
                        
  3. Add the following Imports statements at the top of Module1:

    Imports System
    Imports System.Xml
    Imports System.Xml.XPath
    Imports System.Xml.Xsl
                        
  4. Incrementally add code to implement the following:
    • A Sub Main() procedure that contains the client code to execute XPath queries whose expressions reference user-defined extension functions and a user-defined variable.
    • A custom XsltContext class.
    • A custom IXsltContextFunction class.
    • A custom IXsltContextVariable class.
  5. Paste the following code to implement the Sub Main() procedure in Module1.vb:

    Sub Main()
            Try
    
                'Load source XML into an XPathDocument object instance.
                Dim xmldoc As New XPathDocument("books.xml")
                'Create an XPathNavigator from the XPathDocument. 
                Dim nav As XPathNavigator = xmldoc.CreateNavigator
    
    
                'The user-defined functions in this demo implement equivalents of the commonly
                'used Left(string,length) and Right(string,length) VB string functions.
    
                'Compile 2 XPath query expressions that use the user-defined XPath functions and a user-defined variable.
                'The Compilation step only checks the query expression for correct tokenization. It does not 
                'attempt to resolve or verify the definition or validity of the function and variable names
                'used in the query expression. 
                Dim expr1 As XPathExpression = nav.Compile("myFuncs:left(string(.),$length)")
                Dim expr2 As XPathExpression = nav.Compile("myFuncs:right(string(.),$length)")
    
                'Instantiate an XsltArgumentList object. 
                Dim varList As New XsltArgumentList()
                'Add the user-defined variable to the XsltArgumentList object
                'and supply a value for it.
                varList.AddParam("length", "", 5)
    
                'Instantiate a custom XsltContext object. This object will be used to 
                'resolve the references to the user-defined XPath extension functions and the
                'user-defined variable at execution time. 
    
                'Notice that in the Ctor you are also passing in the XsltArgumentList object 
                'in which the user-defined variable is defined.
                Dim cntxt As New CustomContext(New NameTable(), varList)
    
                'Add a namespace definition for the ns prefix that qualifies the user-defined 
                'function names in the expr1 and expr2 query expressions.
                cntxt.AddNamespace("myFuncs", "http://myXPathExtensionFunctions")
    
                'Associate the custom XsltContext object with the 2 XPathExpression objects
                'whose query expressions use the custom XPath functions and the custom variable.
                expr1.SetContext(cntxt)
                expr2.SetContext(cntxt)
    
                'Instantiate an XPathNodeIterator to navigate through all the Title nodes
                'in the source XML.
                Dim iter As XPathNodeIterator = nav.Select("/Books/Title")
                Do While iter.MoveNext
                    'Write the full content of the current Title element node.
                    Console.WriteLine("Title : " & iter.Current.Value)
                    'Apply XPathExpression expr1 to the current Title element node
                    'to extract and display the first 5 (value supplied for the length variable) characters [myFuncs:left(.,$length)]
                    Console.WriteLine(vbTab & "left() : " & iter.Current.Evaluate(expr1))
                    'Apply XPathExpression expr2 to the current Title element node
                    'to extract and display the last 5 (value supplied for the length variable) characters [myFuncs:right(.,$length)]
                    Console.WriteLine(vbTab & "right() : " & iter.Current.Evaluate(expr2))
                Loop
            Catch exp As Exception
                Console.WriteLine(exp.ToString)
            End Try
    
            Dim response As String = Console.ReadLine
    
     End Sub
                        

    Three XPath query expressions are used in this code. The following query expression is executed first to retrieve all the title nodes in Books.xml. This query expression does not reference any custom extension functions or user-defined variables:

    /Books/Title
                        

    The other two following query expressions use custom extension functions that mimic the Visual Basic left and right string functions, and a user-defined variable to extract a specified number of left-most and right-most characters from each title node that is returned by the first XPath query:

    myFuncs:left(string(.),$length)
    myFuncs:right(string(.),$length)
                        

    Custom XsltContext, IXsltContextFunction, and IXsltContextVariable objects are used to resolve the references to the extension functions and user-defined variable.

    The following is a description of the code in this section:

    First, the code instantiates an XPathDocument object and loads the data in Books.xml into it. The CreateNavigator method of the XPathDocument object is then used to execute the XPath queries against the data:

    Dim xmldoc As New XPathDocument("books.xml")
    Dim nav As XPathNavigator = xmldoc.CreateNavigator
                        

    Next, the code compiles the two query expressions that are applied to each of the Title nodes in Books.xml to extract a specified number of left-most and right-most characters from the node value. Notice that these query expressions use the left and right custom XPath extension functions to extract the required characters. Also notice that a user-defined variable named length is used to specify the number of characters to extract:

    Dim expr1 As XPathExpression = nav.Compile("myFuncs:left(string(.),$length)")
    Dim expr2 As XPathExpression = nav.Compile("myFuncs:right(string(.),$length)")
                        

    The code then instantiates an XsltArgumentList object and uses its AddParam method to define the user-defined variable length, and then supplies a value for it that is used at run time when it executes the query expression. The assigned value of 5 results in the 5 left-most and right-most characters being extracted from the value of each title node that these two query expressions are applied to:

    Dim varList As New XsltArgumentList()
    varList.AddParam("length", "", 5)
                        

    This XsltArgumentList object is supplied as a parameter when the custom XsltContext object is instantiated. A property of the custom XsltContext object is used to reference it (you will see this when you later examine the code that is used to implement the custom XsltContext). The custom XsltContext object that is associated with the XPathExpression objects is passed as a parameter to the Evaluate method of the custom IXsltContextVariable object that is used by the XPath processor to resolve references to user-defined variables:

    Dim cntxt As New CustomContext(New NameTable(), varList)
                        

    Next, the code adds a definition for the custom namespace prefix that is used to qualify the references to the extension functions in the query expressions:

    cntxt.AddNamespace("myFuncs", "http://myXPathExtensionFunctions")
                        

    The code then associates the custom context with the XPathExpression objects that are used to execute the XPath query expressions that reference the extension functions and user-defined variable:

    expr1.SetContext(cntxt)
    expr2.SetContext(cntxt)
                        

    In the execution of the actual XPath queries, the code first executes an XPath query by using the Select method of the XPathNavigator to retrieve all the Title nodes in Books.xml:

    Dim iter As XPathNodeIterator = nav.Select("/Books/Title")
                        

    The returned XPathNodeIterator is used to move through the returned node set. In the loop, the value of the current Title node is displayed and the Evaluate method of the XPathNavigator is used to apply the two XPath query expressions that extract the specified number of left-most and right-most characters from the node value. The data that is returned by executing these expressions is also displayed in the console window:

    Do While iter.MoveNext
           Console.WriteLine("Title : " & iter.Current.Value)
           Console.WriteLine(vbTab & "left() : " & iter.Current.Evaluate(expr1))
           Console.WriteLine(vbTab & "right() : " & iter.Current.Evaluate(expr2))
    Loop
                        
  6. Paste the following code after the definition of Module1 in Module1.vb to implement the custom IXsltContext class:

    Public Class CustomContext
        Inherits System.Xml.Xsl.XsltContext
    
        'XsltArgumentList to store definitions (names and values) of user-defined variables
        'that can be accessed by XPath query expressions evaluated using an object instance
        'of this class as the XsltContext. 
        Private m_ArgList As XsltArgumentList
    
        'Implement Ctors.
        Public Sub New()
            MyBase.New()
        End Sub
    
        Public Sub New(ByVal nt As NameTable, ByVal args As XsltArgumentList)
            MyBase.New(nt)
            m_ArgList = args        
        End Sub
    
        'Function to resolve references to user-defined XPath extension functions in XPath query 
        'expressions evaluated using an object instance of this class as the XsltContext. 
    
        'This function will instantiate and return an instance of the XPathExtensionFunctions custom class 
        'that implements the IXsltContextFunction interface. 
         Public Overrides Function ResolveFunction(ByVal prefix As String, ByVal [name] As String, _ 
            ByVal ArgTypes() As System.Xml.XPath.XPathResultType) As System.Xml.Xsl.IXsltContextFunction
          Dim func As XPathStringExtensionFunctions
          Const MINARGS As Integer = 2, MAXARGS As Integer = 2
          If name = "left" Then
             'Instantiate an XPathStringExtensionObjects class by supplying parameters that map to the user-defined XPath 
             'extension function left(). The Invoke method of the returned object will be used at run-time to execute the left() function.
             func = New XPathStringExtensionFunctions(MINARGS, MAXARGS, XPathResultType.String, Nothing, "left")
          ElseIf name = "right" Then
             'Instantiate an XPathStringExtensionObjects class by supplying parameters that map to the user-defined XPath 
             'extension function right(). The Invoke method of the returned object will be used at run-time to execute the right() function.
             func = New XPathStringExtensionFunctions(MINARGS, MAXARGS, XPathResultType.String, Nothing, "right")
          End If
    
          'Return the XPathStringExtensionFunctions object instance.
          Return func
       End Function
    
       'Function to resolve references to user-defined XPath extension variables in XPath query.
        Public Overrides Function ResolveVariable(ByVal prefix As String, ByVal [name] As String) As System.Xml.Xsl.IXsltContextVariable
            'Instantiate an XPathExtensionVariable (Custom IXsltContextVariable implementation) object 
            'by supplying the name of the user-defined variable to resolve.
            Dim Var As XPathExtensionVariable
            Var = New XPathExtensionVariable([name])
    
            'Return the instantiated XPathExtensionVariable object. The Evaluate method of the 
            'returned object will be used at run time to resolve the user-defined variable referenced
            'in the XPath query expression. 
            Return Var
        End Function
    
        Public Overrides Function PreserveWhitespace(ByVal node As System.Xml.XPath.XPathNavigator) As Boolean
    
        End Function
    
        Public Overrides Function CompareDocument(ByVal baseUri As String, ByVal nextbaseUri As String) As Integer
    
        End Function
    
        Public Overrides ReadOnly Property Whitespace() As Boolean
            Get
    
            End Get
        End Property
    
        'Returns the XsltArgumentList containing the user-defined variable definitions (names and values). 
        'This property will be accessed by the Evaluate method of the XPathExtensionVariable object instance
        'returned by the ResolveVariable method of this class to resolve references to user-defined variables 
        'in XPath query expressions. 
        Public ReadOnly Property ArgList() As XsltArgumentList
            Get
                Return m_ArgList
            End Get
        End Property
    End Class
                        

    In this sample, the custom XsltContext is implemented by a user-defined class named CustomContext that inherits from the abstract base class XsltContext that is implemented in the System.Xml.Xsl namespace.

    This class defines a private XsltArgumentList field that is used to hold a reference to the XsltArgumentList object that contains definitions of user-defined variables that are supplied by the client code that instantiates an object instance of this custom context. This field is made accessible to external components through a public read-only property named ArgList. The code in the constructor that is used by the client code assigns the XsltArgumentList object parameter that contains definitions for the user-defined variables to the private XsltArgumentList field named m_ArgList:

    Public Sub New(ByVal nt As NameTable, ByVal args As XsltArgumentList)
            MyBase.New(nt)
            m_ArgList = args        
    End Sub
                        

    View the code in the overridden ResolveFunction and ResolveVariable methods that are invoked by the XPath processor when it finds the user-defined extension functions and variable in the XPath query expressions. The code in the ResolveFunction method creates and returns an object instance of the custom IXsltContextFunction class named XPathStringExtensionFunctions. This defines and implements the user-defined functions named left and right that are referenced in the query expressions. The Invoke method of the returned IXsltContextFunction object is used by the XPath processor to execute the extension functions:

    Public Overrides Function ResolveFunction(ByVal prefix As String, ByVal [name] As String, _
          ByVal ArgTypes() As System.Xml.XPath.XPathResultType) As System.Xml.Xsl.IXsltContextFunction
          Dim func As XPathStringExtensionFunctions
          Const MINARGS As Integer = 2, MAXARGS As Integer = 2
          If name = "left" Then
             func = New XPathStringExtensionFunctions(MINARGS, MAXARGS, XPathResultType.String, Nothing, "left")
          ElseIf name = "right" Then
             func = New XPathStringExtensionFunctions(MINARGS, MAXARGS, XPathResultType.String, Nothing, "right")
          End If
    
          Return func
       End Function
                        

    The constructor that is used to instantiate the custom IXsltContextFunction object takes parameters that specify values for the minimum and maximum of parameters, the parameter types, the type of the result generated, and the name of the extension function that must be resolved.

    The ResolveFunction method is called one time for each extension function that is referenced in a query expression, and it returns an IXsltContextFunction object instance that is required to resolve the reference.

    The ResolveVariable method instantiates and returns an object instance of the custom IXsltContextVariable class named XPathExtensionVariable, which is required to resolve references to user-defined variables in query expressions. The name of the variable to be resolved is supplied as the parameter when instantiating the IXsltContextVariable object. The Evaluate method of the returned IXsltContextVariable object is used by the XPath processor to resolve the reference to a user-defined variable:

    Public Overrides Function ResolveVariable(ByVal prefix As String, ByVal [name] As String) As System.Xml.Xsl.IXsltContextVariable
            Dim Var As XPathExtensionVariable
            Var = New XPathExtensionVariable([name])
           
            Return Var
        End Function
                        

    The ResolveVariable method is called one time for each user-defined variable that is referenced in a query expression, and it returns an IXsltContextVariable object instance that is required to resolve the reference.

    Note that the methods that are specific to XSLT (PreserveWhitespace and CompareDocument) have no implementation. As mentioned earlier, Microsoft recommends using XSLT extension objects or inline script blocks to implement extension functions for XPath queries in XSLT style sheets.

  7. Paste the following code after the definition of the custom XsltContext class in Module1.vb to implement the custom IXsltContextFunction class:

    'An object instance of this class will be used
    'as an interface to resolve and execute a specified user-defined function. 
    Public Class XPathStringExtensionFunctions
        Implements System.Xml.Xsl.IXsltContextFunction
    
        'The data types of the arguments passed to the custom XPath extension function that an object instance is used to execute.
        Private m_ArgTypes() As System.Xml.XPath.XPathResultType
        'The minimum number of arguments that must be passed to a custom XPath extension function that an object instance is used to execute.
        Private m_MinArgs As Integer
        'The maximum number of arguments that must be passed to a custom XPath extension function that an object instance is used to execute.
        Private m_MaxArgs As Integer
        'The data type of the return value of a custom XPath extension function that an object instance is used to execute.
        Private m_ReturnType As System.Xml.XPath.XPathResultType
        'The name of the custom XPath extension function that an object instance will be used to execute.
        Private FunctionName As String
    
        'Constructor used in the ResolveFunction method of the custom XsltContext Class (CustomContext) 
        'to instantiate and return an IXsltContextFunction object to execute a specified user-defined 
        'XPath extension function at run time. 
        Public Sub New(ByVal p_minArgs As Integer, ByVal p_maxArgs As Integer, ByVal p_ReturnType As XPathResultType, _
          ByVal p_ArgTypes() As XPathResultType, ByVal p_FunctionName As String)
            Me.m_MinArgs = p_minArgs
            Me.m_MaxArgs = p_maxArgs
            Me.m_ReturnType = p_ReturnType
            Me.m_ArgTypes = p_ArgTypes
            Me.FunctionName = p_FunctionName
        End Sub
    
        'Read-only property methods to access the private fields.
        Public ReadOnly Property ArgTypes() As System.Xml.XPath.XPathResultType() Implements System.Xml.Xsl.IXsltContextFunction.ArgTypes
    
            Get
                Return m_ArgTypes
            End Get
        End Property
    
        Public ReadOnly Property Maxargs() As Integer Implements System.Xml.Xsl.IXsltContextFunction.Maxargs
            Get
                Return m_MaxArgs
            End Get
        End Property
    
        Public ReadOnly Property Minargs() As Integer Implements System.Xml.Xsl.IXsltContextFunction.Minargs
            Get
                Return m_MinArgs
            End Get
        End Property
    
        Public ReadOnly Property ReturnType() As System.Xml.XPath.XPathResultType Implements System.Xml.Xsl.IXsltContextFunction.ReturnType
            Get
                Return m_ReturnType
            End Get
        End Property
    
        'The 2 custom XPath extension functions.
        Private Function left(ByVal value As String, ByVal length As Integer) As String
            Return Microsoft.VisualBasic.Left(value, length)
        End Function
    
        Private Function right(ByVal value As String, ByVal length As Integer) As String
            Return Microsoft.VisualBasic.Right(value, length)
        End Function
    
        'Function to execute a specified user-defined XPath extension function at run time.
        Public Function Invoke(ByVal xsltContext As System.Xml.Xsl.XsltContext, ByVal args() As Object, _
          ByVal docContext As System.Xml.XPath.XPathNavigator) As Object Implements System.Xml.Xsl.IXsltContextFunction.Invoke
            If FunctionName = "left" Then
                Return left(args(0), args(1))
            ElseIf FunctionName = "right" Then
                Return right(args(0), args(1))
            End If
    
        End Function
    
    End Class
                        

    The XPathStringExtensionFunctions class implements the IXsltContextFunction interface that is defined in the System.Xml.Xsl namespace.

    The private fields directly map to the parameters that are passed in when an object instance of this class is instantiated in the ResolveFunction method of the custom XsltContext class. The code in its constructor assigns the passed-in parameters to these private fields:

    Public Sub New(ByVal p_minArgs As Integer, ByVal p_maxArgs As Integer, ByVal p_ReturnType As XPathResultType, _
          ByVal p_ArgTypes() As XPathResultType, ByVal p_FunctionName As String)
            Me.m_MinArgs = p_minArgs
            Me.m_MaxArgs = p_maxArgs
            Me.m_ReturnType = p_ReturnType
            Me.m_ArgTypes = p_ArgTypes
            Me.FunctionName = p_FunctionName
        End Sub
                        

    Public read-only properties are implemented to make these fields accessible to external objects.

    The following code implements the two extension functions that are used in this sample. These functions use the Left and Right string functions that are implemented in the Microsoft.VisualBasic namespace to extract and return the required left-most and right-most characters:

    'The 2 custom XPath extension functions.
        Private Function left(ByVal value As String, ByVal length As Integer) As String
            Return Microsoft.VisualBasic.Left(value, length)
        End Function
    
        Private Function right(ByVal value As String, ByVal length As Integer) As String
            Return Microsoft.VisualBasic.Right(value, length)
        End Function
                        

    Finally, the implementation of the Invoke method is used by the XPath processor to execute an extension function:

    Public Function Invoke(ByVal xsltContext As System.Xml.Xsl.XsltContext, ByVal args() As Object, _
          ByVal docContext As System.Xml.XPath.XPathNavigator) As Object Implements System.Xml.Xsl.IXsltContextFunction.Invoke
            If FunctionName = "left" Then
                Return left(args(0), args(1))
            ElseIf FunctionName = "right" Then
                Return right(args(0), args(1))
            End If
    End Function
                        

    This function executes the extension function whose name was specified when an object instance of this class was instantiated in the ResolveFunction method of the custom XsltContext. The output that is generated by executing the function is returned to the XPath processor.

  8. Paste the following code after the definition of the custom IXsltContextFunction class in Module1.vb to implement the custom IXsltContextVariable class:

    'Class that implements the System.Xml.Xsl.IXsltContextVariable interface.
    'This class will be used to resolve references to user-defined variables in 
    'XPath query expressions at run time. An object instance of this class will be created and returned
    'by the overridden ResolveVariable function of the custom XsltContext class (CustomContext). 
    Public Class XPathExtensionVariable
        Implements IXsltContextVariable
    
        'The name of the user-defined variable to resolve.
        Private m_VarName As String
    
        'Constructor used in the overridden ResolveVariable function of the custom XsltContext class (CustomContext).
        Public Sub New(ByVal VarName As String)
            m_VarName = VarName
        End Sub
    
        'Function to return the value of the specified user-defined variable.
        'Uses the GetParam method of the XsltArgumentList property of the current active custom XsltContext
        'object to access and return the value assigned to the specified variable.
        Public Function Evaluate(ByVal xsltContext As System.Xml.Xsl.XsltContext) As Object Implements System.Xml.Xsl.IXsltContextVariable.Evaluate
            Dim vars As XsltArgumentList = CType(XsltContext, CustomContext).ArgList
            Return vars.GetParam(m_VarName, Nothing)
        End Function
    
        'Is it a local XSLT variable? Not applicable when not using a style sheet.
        Public ReadOnly Property IsLocal() As Boolean Implements System.Xml.Xsl.IXsltContextVariable.IsLocal
            Get
                Return False
            End Get
        End Property
    
        'Is it an XSLT parameter? Not applicable when not using a style sheet.
        Public ReadOnly Property IsParam() As Boolean Implements System.Xml.Xsl.IXsltContextVariable.IsParam
            Get
                Return False
            End Get
        End Property
    
        'The System.Xml.XPath.XPathResultType of the variable.
        Public ReadOnly Property VariableType() As System.Xml.XPath.XPathResultType Implements System.Xml.Xsl.IXsltContextVariable.VariableType
            Get
                Return XPathResultType.Any
            End Get
        End Property
    End Class
                        

    The XPathExtensionVariable class implements the IXsltContextVariable interface that is defined in the System.Xml.Xsl namespace.

    The private field m_VarName is used to store the value of the parameter that is passed in when an object instance of this class is instantiated in the ResolveVariable method of the custom XsltContext class. It represents the name of the user-defined variable that an object instance of this class is used to resolve. The variable name that is passed in as a parameter to the constructor is assigned to this field:

    Public Sub New(ByVal VarName As String)
            m_VarName = VarName
    End Sub
                        

    The Evaluate method is invoked by the XPath processor to resolve a reference to a user-defined variable. The custom XsltContext is passed as a parameter to this method. The code in this method resolves the reference to the specified user-defined variable by accessing the XsltArgumentList property of the custom XsltContext object. The variable definitions are added to this argument list object, which is supplied as a parameter while instantiating the custom context object:

    Public Function Evaluate(ByVal xsltContext As System.Xml.Xsl.XsltContext) As Object Implements System.Xml.Xsl.IXsltContextVariable.Evaluate
            Dim vars As XsltArgumentList = CType(XsltContext, CustomContext).ArgList
            Return vars.GetParam(m_VarName, Nothing)
    End Function
                        

    Now that you understand the implementation of the code, you can execute the sample application and evaluate the output.

back to the top

Test the Sample Application

To test the XPathExtensionFunctions sample application, follow these steps:

  1. Save and build the solution.
  2. Execute the project and examine the output. The output that is generated displays both the value of each title node that is extracted by the first XPath query to retrieve all title nodes and the output that is generated by executing the XPath expressions that use the extension functions and user-defined variable to extract the five left-most and right-most characters from each title.

back to the top

REFERENCES

For additional information, click the following article numbers to view the articles in the Microsoft Knowledge Base:

313828 INFO: Roadmap for Executing XPath Queries in .NET Applications


back to the top

Keywords: kbhowtomaster KB324899