Lookhill
Lookhill

Reputation: 53

Create custom tag extending XSLT using .NET

Is there a way to create custom tag extending XSLT in a similar way to custom function?

ie (in my xslt file):

<xsl:template match="/">
<div>
  <my:customTag items="3" classname="foo"/>
</div>
</xsl:template>

expected output:

<div>
  <ul class="foo">
    <li>...</li>
    <li>...</li>
    <li>...</li>
  </ul>
<div>

Currently I'm doing this:

<xsl:template match="/">
<div>
  <xsl:copy-of select="my:customFunc(3,'foo')" />
</div>
</xsl:template>

and my customFunc in vb code do something like this:

Public Function customFunc(ByVal n As Integer, ByVal classname as String) As System.Xml.XmlNode
            Dim newNode As System.Xml.XmlNode
            Dim doc As System.Xml.XmlDocument = New System.Xml.XmlDocument()
            Dim xmlContent As String = "<ul class=""" + classname + """>"

            For v As Integer = 0 To n
                xmlContent += "<li>" + someComplicatedCalc(n) + "</li>"
            Next
            xmlContent += "</ul>"


            doc.LoadXml(xmlContent)
            newNode = doc.DocumentElement

            Return newNode
        End Function

but I want to use tags instead of functions.

Upvotes: 0

Views: 207

Answers (3)

Matthew Whited
Matthew Whited

Reputation: 22443

If you want to use your existing VB.Net code but have nicer syntax in your source XML try adding this template to your stylesheet.

<xsl:template match="my:customTag">
  <xsl:copy-of select="my:customFunc(@items,@classname)" />
</xsl:template>

The xpath selector will use your <my:customTag items="3" classname="foo"/>

Upvotes: 1

Dan Field
Dan Field

Reputation: 21651

If you're looking for a way to replace your VB function with just XSLT, you could do something like this:

<xsl:template match="my:customTag">
    <ul class="{@classname}">
      <xsl:call-template name="expand_customTag">
        <xsl:with-param name="i" select="1" />
        <xsl:with-param name="count" select="@items" />
      </xsl:call-template>
    </ul>
</xsl:template>
<xsl:template name="expand_customTag">
    <xsl:param name="i" />
    <xsl:param name="count" />
    <il>....</il>
    <xsl:if test="$i &lt; $count">
      <xsl:call-template name="expand_customTag">
        <xsl:with-param name="i" select="$i + 1" />
        <xsl:with-param name="count" select="$count" />
      </xsl:call-template>
    </xsl:if>
</xsl:template>

The idea is using a recursive template to produce your <il> elements, and this would make your XSLT more portable to other XSLT processors.

Upvotes: 1

Martin Honnen
Martin Honnen

Reputation: 167571

I am not aware of any support for this feature called custom extension elements with Microsoft's XslCompiledTransform and other processors, like XmlPrime or like Saxon (http://saxonica.com/html/documentation9.6/extensibility/instructions.html) don't seem to support it either with .NET.

Upvotes: 1

Related Questions