Compartilhar via


Blocos de script usando msxsl:script

Observação

Os blocos de script têm suporte apenas no .NET Framework. Eles não têm suporte no .NET Core ou no .NET 5 ou posterior.

A XslCompiledTransform classe dá suporte a scripts inseridos usando o msxsl:script elemento. Quando a folha de estilos é carregada, quaisquer funções definidas são compiladas para CIL (linguagem intermediária comum) pelo CodeDOM e são executadas durante o tempo de execução. O assembly gerado no bloco de script inserido é separado do assembly gerado para a folha de estilos.

Habilitar script XSLT

O suporte para scripts inseridos é uma configuração XSLT opcional na XslCompiledTransform classe. O suporte a scripts está desabilitado por padrão. Para habilitar o suporte ao script, crie um objeto XsltSettings com a propriedade EnableScript definida como true e passe o objeto para o método Load.

Aviso

A partir do .NET 10, a EnableScript propriedade é marcada como obsoleta e gera SYSLIB0062 de aviso. Como não há suporte para blocos de script no .NET Core ou no .NET 5+, essa propriedade não tem nenhum efeito, e ao defini-la como true, uma PlatformNotSupportedException é lançada em tempo de execução.

Observação

O script XSLT só deve ser habilitado se você precisar de suporte de script e estiver trabalhando em um ambiente totalmente confiável.

Definição do elemento msxsl:script

O msxsl:script elemento é uma extensão da Microsoft para a recomendação XSLT 1.0 e tem a seguinte definição:

<msxsl:script language = "language-name" implements-prefix = "prefix of user namespace"> </msxsl:script>

O msxsl prefixo está associado ao URI do urn:schemas-microsoft-com:xslt namespace. A folha de estilos deve incluir a declaração de xmlns:msxsl=urn:schemas-microsoft-com:xslt namespace.

O atributo language é opcional. Seu valor é a linguagem de código do bloco de código inserido. O idioma é mapeado para o compilador CodeDOM apropriado usando o CodeDomProvider.CreateProvider método. A XslCompiledTransform classe pode dar suporte a qualquer idioma do Microsoft .NET, supondo que o provedor apropriado esteja instalado no computador e esteja registrado na seção system.codedom do arquivo machine.config. Se um atributo language não for especificado, o idioma padrão será JScript. O nome do idioma não diferencia maiúsculas de minúsculas, portanto, 'JavaScript' e 'javascript' são equivalentes.

O implements-prefix atributo é obrigatório. Esse atributo é usado para declarar um namespace e associá-lo ao bloco de script. O valor desse atributo é o prefixo que representa o namespace. Esse prefixo pode ser definido em algum lugar em uma folha de estilos.

Observação

Ao usar o msxsl:script elemento, é altamente recomendável que o script, independentemente da linguagem, seja colocado dentro de uma seção CDATA. Como o script pode conter operadores, identificadores ou delimitadores para um determinado idioma, se ele não estiver contido em uma seção CDATA, ele terá o potencial de ser interpretado incorretamente como XML. O XML a seguir mostra um modelo da seção CDATA em que o código pode ser colocado.

<msxsl:script implements-prefix='your-prefix' language='CSharp'>
<![CDATA[
// Code block.
]]>
</msxsl:script>

Funções de script

As funções podem ser declaradas dentro do msxsl:script elemento. Quando uma função é declarada, ela está contida em um bloco de script. As folhas de estilo podem conter vários blocos de script, cada um operando independentemente do outro. Isso significa que, se você estiver executando dentro de um bloco de script, não poderá chamar uma função que você definiu em outro bloco de script, a menos que ela seja declarada com o mesmo namespace e a mesma linguagem de script. Como cada bloco de script pode estar em seu próprio idioma e o bloco é analisado de acordo com as regras gramaticais desse analisador de idioma, recomendamos que você use a sintaxe correta para o idioma em uso. Por exemplo, se você estiver em um bloco de script do Microsoft C#, use a sintaxe de comentário em C#.

Os argumentos fornecidos e os valores retornados para a função podem ser de qualquer tipo. Como os tipos XPath W3C são um subconjunto dos tipos CLR (Common Language Runtime), a conversão de tipo ocorre em tipos que não são considerados um tipo XPath. A tabela a seguir mostra os tipos W3C correspondentes e o tipo CLR equivalente.

Tipo W3C Tipo CLR
String String
Boolean Boolean
Number Double
Result Tree Fragment XPathNavigator
Node Set XPathNodeIterator

Os tipos numéricos CLR são convertidos em Double. O DateTime tipo é convertido Stringem . IXPathNavigable os tipos são convertidos em XPathNavigator. XPathNavigator[] é convertido em XPathNodeIterator.

Todos os outros tipos retornam um erro.

Importar namespaces e assemblies

A XslCompiledTransform classe predefini um conjunto de assemblies e namespaces com suporte por padrão pelo msxsl:script elemento. No entanto, você pode usar classes e membros pertencentes a um namespace que não constam na lista predefinida, importando o assembly e o namespace em bloco msxsl:script.

Assembléias

Os dois conjuntos a seguir são referenciados por padrão:

  • System.dll
  • System.Xml.dll
  • Microsoft.VisualBasic.dll (quando a linguagem de script é VB)

Você pode importar os assemblies adicionais usando o msxsl:assembly elemento. Isso inclui o assembly quando a folha de estilos é compilada. O msxsl:assembly elemento tem a seguinte definição:

<msxsl:script>
  <msxsl:assembly name="system.assemblyName" />
  <msxsl:assembly href="path-name" />
    <![CDATA[
    // User code
    ]]>
</msxsl:script>

O name atributo contém o nome do assembly e o href atributo contém o caminho para o assembly. O nome do assembly pode ser um nome completo, como "System.Data, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" ou um nome curto, como "System.Web".

Namespaces

Os namespaces a seguir são incluídos por padrão:

  • Sistema
  • System.Collection
  • System.Text
  • System.Text.RegularExpressions
  • System.Xml
  • System.Xml.Xsl
  • System.Xml.XPath
  • Microsoft.VisualBasic (quando a linguagem de script é VB)

Você pode adicionar suporte para namespaces adicionais usando o namespace atributo. O valor do atributo é o nome do namespace.

<msxsl:script>
  <msxsl:using namespace="system.namespaceName" />
    <![CDATA[
    // User code
    ]]>
</msxsl:script>

Exemplo

O exemplo a seguir usa um script inserido para calcular a circunferência de um círculo dado seu raio.

using System;
using System.IO;
using System.Xml;
using System.Xml.XPath;
using System.Xml.Xsl;

public class Sample {

  private const String filename = "number.xml";
  private const String stylesheet = "calc.xsl";

  public static void Main() {

    // Compile the style sheet.
    XsltSettings xslt_settings = new XsltSettings();
    xslt_settings.EnableScript = true;
    XslCompiledTransform xslt = new XslCompiledTransform();
    xslt.Load(stylesheet, xslt_settings, new XmlUrlResolver());

    // Load the XML source file.
    XPathDocument doc = new XPathDocument(filename);

    // Create an XmlWriter.
    XmlWriterSettings settings = new XmlWriterSettings();
    settings.OmitXmlDeclaration = true;
    settings.Indent = true;
    XmlWriter writer = XmlWriter.Create("output.xml", settings);

    // Execute the transformation.
    xslt.Transform(doc, writer);
    writer.Close();
  }
}
Imports System.IO
Imports System.Xml
Imports System.Xml.XPath
Imports System.Xml.Xsl

Public class Sample

    Private Const filename As String = "number.xml"
    Private Const stylesheet As String = "calc.xsl"

    Public Shared Sub Main()

        ' Compile the style sheet.
        Dim xslt_settings As XsltSettings = New XsltSettings()
        xslt_settings.EnableScript = true
        Dim xslt As XslCompiledTransform = New XslCompiledTransform()
        xslt.Load(stylesheet, xslt_settings, New XmlUrlResolver())

        ' Load the XML source file.
        Dim doc As XPathDocument = New XPathDocument(filename)

        ' Create an XmlWriter.
        Dim settings As XmlWriterSettings = New XmlWriterSettings()
        settings.OmitXmlDeclaration = true
        settings.Indent = true
        Dim writer As XmlWriter = XmlWriter.Create("output.xml", settings)

        ' Execute the transformation.
        xslt.Transform(doc, writer)
        writer.Close()
    End Sub
End Class

number.xml

<?xml version='1.0'?>
<data>
  <circle>
    <radius>12</radius>
  </circle>
  <circle>
    <radius>37.5</radius>
  </circle>
</data>

calc.xsl

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:msxsl="urn:schemas-microsoft-com:xslt"
  xmlns:user="urn:my-scripts">
  <msxsl:script language="C#" implements-prefix="user">
  <![CDATA[
  public double circumference(double radius){
    double pi = 3.14;
    double circ = pi*radius*2;
    return circ;
  }
  ]]>
  </msxsl:script>
  <xsl:template match="data">
    <circles>
      <xsl:for-each select="circle">
        <circle>
          <xsl:copy-of select="node()"/>
          <circumference>
            <xsl:value-of select="user:circumference(radius)"/>
          </circumference>
        </circle>
      </xsl:for-each>
    </circles>
  </xsl:template>
</xsl:stylesheet>

Saída

<circles xmlns:msxsl="urn:schemas-microsoft-com:xslt" xmlns:user="urn:my-scripts">
  <circle>
    <radius>12</radius>
    <circumference>75.36</circumference>
  </circle>
  <circle>
    <radius>37.5</radius>
    <circumference>235.5</circumference>
  </circle>
</circles>

Consulte também