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>