Partilhar via


blocos de script usando msxsl:script

Nota

Os blocos de script são suportados apenas no .NET Framework. Eles não são suportados no .NET Core ou .NET 5 ou posterior.

A XslCompiledTransform classe suporta scripts incorporados usando o msxsl:script elemento . Quando a folha de estilos é carregada, todas as funções definidas são compiladas para linguagem intermediária comum (CIL) pelo Code Document Object Model (CodeDOM) e são executadas durante o tempo de execução. O assembly gerado a partir do bloco de script incorporado é separado do assembly gerado para a folha de estilos.

Ativar script XSLT

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

Nota

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

msxsl:definição de elemento de 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á vinculado ao URI do urn:schemas-microsoft-com:xslt namespace. A folha de estilos deve incluir a xmlns:msxsl=urn:schemas-microsoft-com:xslt declaração de namespace.

O language atributo é opcional. Seu valor é a linguagem de código do bloco de código incorporado. A linguagem é mapeada para o compilador CodeDOM apropriado usando o CodeDomProvider.CreateProvider método. A XslCompiledTransform classe pode suportar qualquer linguagem Microsoft .NET, supondo que o provedor apropriado esteja instalado na máquina e registrado na seção system.codedom do arquivo machine.config. Se um language atributo não for especificado, o padrão da linguagem será JScript. O nome da linguagem 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.

Nota

Ao usar o msxsl:script elemento , é altamente recomendável que o script, independentemente do idioma, seja colocado dentro de uma seção CDATA. Como o script pode conter operadores, identificadores ou delimitadores para uma determinada linguagem, se ele não estiver contido em uma seção CDATA, ele tem o potencial de ser interpretado incorretamente como XML. O XML a seguir mostra um modelo da seção CDATA onde 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 definida em outro bloco de script, a menos que seja declarado ter 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 linguagem, recomendamos que você use a sintaxe correta para o idioma em uso. Por exemplo, se você estiver em um bloco de script Microsoft C#, use a sintaxe de comentário C#.

Os argumentos fornecidos e os valores de retorno para a função podem ser de qualquer tipo. Como os tipos XPath do 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 em String. IXPathNavigable tipos são convertidos em XPathNavigator. XPathNavigator[] é convertido em XPathNodeIterator.

Todos os outros tipos lançam um erro.

Importando namespaces e assemblies

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

Assemblagens

Os dois assemblies 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 a montagem 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".

Espaços de nomes

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 incorporado 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