Olá pessoal, vamos ver como utilizar funções definidas em C# dentro de documentos XSLT.

Considere o simples xml abaixo:

   1: <?xml version="1.0" encoding="utf-8" ?>

   2: <entities>

   3:   <entity>

   4:     <name value="Carlos"></name>

   5:   </entity>

   6: </entities>

 

Temos o seguinte XSLT com algumas chamas a funções:

   1: <xsl:stylesheet version="2.0"

   2:   xmlns:xsl="http://www.w3.org/1999/XSL/Transform"

   3:   xmlns:fo="http://www.w3.org/1999/XSL/Format"

   4:   xmlns:xhtml="http://www.w3.org/1999/xhtml"

   5:   xmlns:xslFunctions="urn:MyXslExtensions"

   6: >

   7:   <xsl:template match="entities/entity">

   8:     <xsl:value-of select ="xslFunctions:WriteMyContent()"/>

   9:     -

  10:     <xsl:value-of select ="xslFunctions:WriteEntityName(.)"/>

  11:   </xsl:template>

  12:  

  13: </xsl:stylesheet>

 

Logo no cabeçalho podemos reparar uma nova definição:

   1: xmlns:xslFunctions="urn:MyXslExtensions"

Aqui estou definindo um novo namespace de nome xslFunctions e defino que ele será encontrado na urn:urn:MyXslExtensions

O arquivo MyXslExtensions está no mesmo namespace mas vocês vão ver que poderia estar em qualquer outro, segue a definição do arquivo:

   1: namespace XmlExtensionsUsingCSharp

   2: {

   3:     public class MyXslExtensions

   4:     {

   5:         public String WriteMyContent()

   6:         {

   7:             return "MyXslExtensionstext";

   8:         }

   9:         public String WriteEntityName(System.Xml.XPath.XPathNodeIterator node)

  10:         {

  11:             var entityElements = node.Current.SelectChildren("name", "").GetEnumerator();

  12:             String text = String.Empty;

  13:             while (entityElements.MoveNext())

  14:             {

  15:                 text += (entityElements.Current as XPathNavigator).GetAttribute("value", "");

  16:             }

  17:             return text;

  18:         }

  19:     }

  20: }

 

   1: XslTransform xsl = new XslTransform();

   2:  

   3:           //passando caminho do xslt

   4:           xsl.Load(AppDomain.CurrentDomain.BaseDirectory + "XsltFile.xslt");

   5:  

   6:           System.IO.MemoryStream memoryStream = new System.IO.MemoryStream();

   7:  

   8:           XmlWriter xmlWriter = new XmlTextWriter(memoryStream, System.Text.Encoding.Default);

   9:  

  10:           //Carregando as extensões customizadas

  11:           XsltArgumentList xsltArgumentList = new XsltArgumentList();

  12:           //adiciono uma extensão com a mesma urn definida no xslt

  13:           xsltArgumentList.AddExtensionObject("urn:MyXslExtensions", new MyXslExtensions());

  14:  

  15:           //Inicio a transformação

  16:  

  17:           XmlDocument xmlDocument = new XmlDocument();

  18:           xmlDocument.Load(AppDomain.CurrentDomain.BaseDirectory + "XMLFile1.xml");

  19:           xsl.Transform(xmlDocument, xsltArgumentList, xmlWriter, null);

  20:  

  21:           Byte[] buffer = new Byte[memoryStream.Length];

  22:           buffer = memoryStream.ToArray();

  23:           String content = System.Text.Encoding.Default.GetString(buffer);

  24:           lblValue.Text = content;

 

Voltando ao xslt podemos ver as chamadas para as funções customizadas:

   1: <xsl:value-of select ="xslFunctions:WriteMyContent()"/>

Apenas executamos uma função que retorna uma string

 

   1: <xsl:value-of select ="xslFunctions:WriteEntityName(.)"/>

Executamos uma função que recebe o nó corrente como parâmetro e navega no mesmo usando Xpath para obter o atributo value do elemento name que é filho do elemento entity(elemento corrente no momento da execução)