Search code examples
extension-methodsxsltumbracoxslcompiledtransform

XSLT extension method with variable number of arguments


I'm trying to implement an XSLT extension function with variable number of arguments. If I declare the parameter as an array, a params array, a ICollection, etc. I get the following error (where TYPE_NAME is the type used):

System.Xml.Xsl.XslTransformException: Extension function parameters or return values which have Clr type 'TYPE_NAME' are not supported.

But the Umbraco has a built-in function concat which functions in this way. I looked in Umbraco's source and it looks like this:

public static string concat(XPathNodeIterator nodeset){...}

and in XSLT it is called like this:

concat('a', 'b', 'c')

When I try a similar approach and declare my function as follows:

public static string Test(XPathNodeIterator nodeset){...}

and call it in XSLT in the same way:

Custom:Test('a', 'b', 'c')

I get the following error:

System.Xml.Xsl.XslTransformException: Extension object 'urn:Custom' does not contain a matching 'Test' method that has 3 parameter(s).

I guess the input of concat is somehow transformed in XPathNodeIterator but I am unable to figure how. Any suggestions?


Solution

  • There are two problems with what you are doing:

    1. Methods with the params keyword are not supported as extension functions, as specified in the .NET documentation:

    Remarks

    The params keyword, which allows an unspecified number of parameters to be passed, is currently not supported. XSLT style sheets that utilize methods defined with the params keyword does not work correctly. For more information, see params (C# Reference).

    .2. Only certain types are allowed as parameters for extension functions. These are defined here:

    W3C type             Equivalent .NET class (type)             XPath or XSLT type
    
    String                     System.String                           XPath
    
    Boolean                    System.Boolean                          XPath
    
    Number                     System.Double                           XPath
    
    Result Tree Fragment       System.Xml.XPath.XPathNavigator         XSLT
    
    Node*                      System.Xml.XPath.XPathNavigator         XPath
    
    Node Set                   XPathNodeIterator or XPathNavigator[]   XPath