views:

56

answers:

2

Hi!

I am received the following error while trying to implement a C# extension function in XSLT.

Extension function parameters or return values which have CLR type 'Char[]' are not supported.**

code:

<xsl:variable name="stringList">
  <xsl:value-of select="extension:GetList('AAA BBB CCC', ' ')"/>
</xsl:variable> 

<msxsl:script language="C#" implements-prefix="extension">
<![CDATA[

public string[] GetList(string str, char[] delimiter)
{
   ...
   ...
   return str.Split(delimiter, StringSplitOptions.None);
}

]]>
</msxsl:script>

Can someone explain this error message and how to get past it?

EDIT: I need a solution that still lets me implement the split function and make use of the array returned.

Thanks!

+1  A: 

XSLT extension methods must return a type that is supported within XSL transformations. The following table shows the W3C XPath types and their corresponging .NET type:

W3C XPath Type        | Equivalent .NET Class (Type)
------------------------------------------------------
String                | System.String
Boolean               | System.Boolean
Number                | System.Double
Result Tree Fragment  | System.Xml.XPath.XPathNavigator
Node Set              | System.Xml.XPath.XPathNodeIterator

The table is taken from the section Mapping Types between XSLT and .NET in this MSDN Magazine article.

Instead of returning a string[] array you would have to return an XPathNodeIterator like it is done in the following example:

<msxsl:script implements-prefix="extension" language="C#">
<![CDATA[

public XPathNodeIterator GetList(string str, string delimiter)
{
    string[] items = str.Split(delimiter.ToCharArray(), StringSplitOptions.None);
    XmlDocument doc = new XmlDocument();
    doc.AppendChild(doc.CreateElement("root"));
    using (XmlWriter writer = doc.DocumentElement.CreateNavigator().AppendChild())
    {
        foreach (string item in items)
        {
            writer.WriteElementString("item", item);
        }
    }
    return doc.DocumentElement.CreateNavigator().Select("item");
}
]]>
</msxsl:script>

In your XSL transform you can then iterate over the elements in the returned node set using xsl:for-each:

<xsl:template match="/">
    <root>
        <xsl:for-each select="extension:GetList('one,two,three', ',')">
            <value>
                <xsl:value-of select="."/>
            </value>
        </xsl:for-each>
    </root>
</xsl:template>
0xA3
So I absolutely cannot have any sort of list? I need to use this split function, which gives me a list. How would you suggest getting around this? (this was the other part of my question.. how to get past the error.. but I will update my question to reflect this more clearly..)
developer
@iHeartGreek: I already updated with an example. Would that solve your problem?
0xA3
thanks! I believe this will work. And I then get each value using for-each in the xsl right?
developer
A: 

From http://msdn.microsoft.com/en-us/library/533texsx(VS.71).aspx

The supplied arguments and return values defined by the script functions must be one of the W3C XPath or XSLT types. The following table shows the corresponding W3C types, the equivalent .NET classes (Type), and whether the W3C Type is an XPath Type or XSLT Type.

Alejandro