Esta documentación está archivada y no tiene mantenimiento.

Bloques de secuencias de comandos con msxsl:script

La clase XslCompiledTransform admite secuencias de comandos incrustadas mediante el elemento msxsl:script. Cuando se carga la hoja de estilos, cualquier función definida se compila en el lenguaje intermedio de Microsoft (MSIL) por medio del Modelo de objetos de documento de código (CodeDOM) y se ejecutan en tiempo de ejecución. El ensamblado que se genera a partir del bloque de secuencias de comandos incrustado es distinto al ensamblado que se genera para la hoja de estilos.

Cómo habilitar la secuencia de comandos XSLT

La compatibilidad con secuencias de comandos incrustadas es un valor XSLT opcional de la clase XslCompiledTransform. Esta compatibilidad está deshabilitada de manera predeterminada. Para habilitarla, cree un objeto XsltSettings con el conjunto de propiedades EnableScript establecido en true y pase el objeto al método Load.

NoteNota

La secuencia de comandos XSLT sólo se debería habilitar si necesita compatibilidad con secuencias de comandos o si está trabajando en un entorno de total confianza. Para obtener más información, vea Consideraciones de seguridad de System.Xml.

Definición del elemento msxsl:script

El elemento msxsl:script es una extensión de Microsoft de la recomendación de XSLT 1.0 y tiene la siguiente definición:

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

El prefijo msxsl está enlazado al identificador URI del espacio de nombres urn:schemas-microsoft-com:xslt. La hoja de estilos debe incluir la declaración de espacio de nombres xmlns:msxsl=urn:schemas-microsoft-com:xslt.

El atributo language es opcional. Su valor es el lenguaje de código del bloque de código incrustado. El lenguaje se asigna al compilador CodeDOM apropiado utilizando el método System.CodeDom.Compiler.CodeDomProvider.CreateProvider(System.String). La clase XslCompiledTransform admite cualquier lenguaje de Microsoft .NET Framework, asumiendo que en el equipo está instalado el proveedor apropiado y está registrado en la sección system.codecom del archivo machine.config. Si no se especifica un atributo language, el lenguaje predeterminado es JScript. El nombre del lenguaje no distingue mayúsculas de minúsculas, por lo que 'JavaScript' y 'javascript' son equivalentes.

El atributo implements-prefix es obligatorio. Este atributo se utiliza para declarar un espacio de nombres y asociarlo con el bloque de la secuencia de comandos. El valor de este atributo es el prefijo que representa el espacio de nombres. Este prefijo puede definirse en cualquier parte de la hoja de estilos.

NoteNota

Al utilizar el elemento msxsl:script, se recomienda encarecidamente que la secuencia de comandos, independientemente del lenguaje, se coloque dentro de una sección CDATA. Puesto que la secuencia de comandos puede contener operadores, identificadores o delimitadores para un lenguaje específico, si no está contenido en la sección CDATA, podría interpretarse erróneamente como XML. El siguiente XML muestra una plantilla de la sección CDATA en donde se puede colocar el código.

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

Funciones de la secuencia de comandos

Las funciones se pueden declarar dentro del elemento msxsl:script. Cuando se declara una función, está contenida en un bloque de secuencias de comandos. Las hojas de estilos pueden contener varios bloques de secuencias de comandos que funcionan independientemente unos de otros. Esto significa que si se ejecuta código desde un bloque de secuencias de comandos, no podrá llamar a una función definida en otro bloque a menos que se haya declarado en el mismo espacio de nombres y con el mismo lenguaje de secuencias de comandos. Puesto que cada bloque de secuencia de comandos puede estar en su propio lenguaje, y el bloque se analiza de acuerdo con las reglas de gramática de dicho analizador de lenguaje, se recomienda utilizar la sintaxis correcta para el lenguaje que esté siendo utilizado. Por ejemplo, si está en un bloque de secuencias de comandos de Microsoft C#, utilice la sintaxis de comentarios de C#.

Los argumentos suministrados y los valores devueltos a la función pueden ser de cualquier tipo. Puesto que los tipos XPath del W3C son un subconjunto de los tipos de Common Language Runtime (CLR), la conversión de tipos tiene lugar en los tipos que no se consideran un tipo de XPath. En la siguiente tabla se muestran los tipos del W3C correspondientes y el tipo CLR equivalente.

Tipo del W3C Tipo CLR

String

String

Boolean

Boolean

Number

Double

Result Tree Fragment

XPathNavigator

Node Set

XPathNodeIterator

Los tipos CLR numéricos se convierten en Double. El tipo DateTime se convierte en String. Los tipos IXPathNavigable se convierten en XPathNavigator. XPathNavigator[] se convierte en XPathNodeIterator.

El resto de los tipos inician un error.

Importación de espacios de nombres y ensamblajes

La clase XslCompiledTransform predefine un conjunto de ensamblajes y espacios de nombres que admite de manera predeterminada el elemento msxsl:script. Sin embargo, puede utilizar las clases y los miembros que pertenecen a un espacio de nombres que no está en la lista predefinida importando el ensamblaje y el espacio de nombres del bloque msxsl:script.

Ensamblajes

Se hace referencia a los dos siguientes ensamblajes de manera predeterminada:

  • System.dll

  • System.Xml.dll

  • Microsoft.VisualBasic.dll (cuando el lenguaje de secuencias de comandos es VB)

Puede importar los ensamblajes adicionales utilizando el elemento msxsl:assembly. Esto incluye el ensamblaje cuando se compila la hoja de estilos. El elemento msxsl:assembly tiene la siguiente definición:

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

El atributo name contiene el nombre del ensamblaje y el atributo href contiene la ruta al ensamblaje. El nombre del ensamblaje puede ser un nombre completo como, por ejemplo, "System.Data, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089", o un nombre corto como, por ejemplo, "System.Web".

Espacios de nombres

Los siguientes espacios de nombres están incluidos de manera predeterminada:

  • System

  • System.Collection

  • System.Text

  • System.Text.RegularExpressions

  • System.Xml

  • System.Xml.Xsl

  • System.Xml.Xpath

  • Microsoft.VisualBasic (cuando el lenguaje de secuencias de comandos es VB)

Puede agregar compatibilidad para espacios de nombres adicionales utilizando el atributo namespace. El valor del atributo es el nombre del espacio de nombres.

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

Ejemplo

En el ejemplo siguiente se utiliza una secuencia de comandos incrustada para calcular la longitud de una circunferencia dado su radio.

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();
  }
}

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>

Resultados

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

Vea también

Mostrar: