Tutorial: Generar código mediante plantillas de textoWalkthrough: Generate Code by using Text Templates

La generación de código permite producir código de programa que está fuertemente tipado, pero que se puede modificar con facilidad cuando el modelo de origen cambia.Code generation allows you to produce program code that is strongly typed, and yet can be easily changed when the source model changes. Compare esto con la técnica alternativa de escribir un programa totalmente genérico que acepta un archivo de configuración, que es más flexible, pero produce código que no es tan fácil de leer ni de cambiar y que no tiene un rendimiento tan bueno.Contrast this with the alternative technique of writing a completely generic program that accepts a configuration file, which is more flexible, but results in code that is neither so easy to read and change, nor has such good performance. En este tutorial se muestra esta ventaja.This walkthrough demonstrates this benefit.

Código escrito para leer XMLTyped code for reading XML

El espacio de nombres System.Xml proporciona herramientas completas para cargar un documento XML y navegar por él libremente en memoria.The System.Xml namespace provides comprehensive tools for loading an XML document and then navigating it freely in memory. Desgraciadamente, todos los nodos tienen el mismo tipo, XmlNode.Unfortunately, all the nodes have the same type, XmlNode. Por lo tanto, es muy fácil cometer errores de programación, como esperar el tipo equivocado de nodo secundario o los atributos equivocados.It is therefore very easy to make programming mistakes such as expecting the wrong type of child node, or the wrong attributes.

En este proyecto de ejemplo, una plantilla lee un archivo XML de ejemplo y genera clases que corresponden a cada tipo de nodo.In this example project, a template reads a sample XML file, and generates classes that correspond to each type of node. En el código escrito a mano, puede usar estas clases para navegar por el archivo XML.In the hand-written code, you can use these classes to navigate the XML file. También puede ejecutar la aplicación en otros archivos que usen los mismos tipos de nodo.You can also run your application on any other files that use the same node types. El propósito del archivo XML de ejemplo es proporcionar ejemplos de todos los tipos de nodo con los que quiere que trate su aplicación.The purpose of the sample XML file is to provide examples of all the node types that you want your application to deal with.

Nota

La aplicación xsd.exe, que se incluye con Programa para la mejoraVisual Studio, puede generar clases fuertemente tipadas de archivos XML.The application xsd.exe, which is included with Programa para la mejoraVisual Studio, can generate strongly-typed classes from XML files. La plantilla que se muestra aquí se proporciona como ejemplo.The template shown here is provided as an example.

Este es el archivo de ejemplo:Here is the sample file:

<?xml version="1.0" encoding="utf-8" ?>
<catalog>
  <artist id ="Mike%20Nash" name="Mike Nash Quartet">
    <song id ="MikeNashJazzBeforeTeatime">Jazz Before Teatime</song>
    <song id ="MikeNashJazzAfterBreakfast">Jazz After Breakfast</song>
  </artist>
  <artist id ="Euan%20Garden" name="Euan Garden">
    <song id ="GardenScottishCountry">Scottish Country Garden</song>
  </artist>
</catalog>

En el proyecto que se construye mediante este tutorial, puede escribir código como el siguiente e IntelliSense le presentará los nombres correctos de atributo y elemento secundario mientras escribe:In the project that this walkthrough constructs, you can write code such as the following, and IntelliSense prompts you with the correct attribute and child names as you type:

Catalog catalog = new Catalog(xmlDocument);
foreach (Artist artist in catalog.Artist)
{
  Console.WriteLine(artist.name);
  foreach (Song song in artist.Song)
  {
    Console.WriteLine("   " + song.Text);
  }
}

Compare esto con el código sin tipo que se escribiría sin la plantilla:Contrast this with the untyped code that you might write without the template:

XmlNode catalog = xmlDocument.SelectSingleNode("catalog");
foreach (XmlNode artist in catalog.SelectNodes("artist"))
{
    Console.WriteLine(artist.Attributes["name"].Value);
    foreach (XmlNode song in artist.SelectNodes("song"))
    {
         Console.WriteLine("   " + song.InnerText);
     }
}

En la versión fuertemente tipada, un cambio en el esquema XML producirá cambios a las clases.In the strongly typed version, a change to the XML schema results in changes to the classes. El compilador resalta las partes del código de aplicación que se deben cambiar.The compiler highlights the parts of the application code that must be changed. En la versión sin tipo que usa código XML genérico, no existe esa posibilidad.In the untyped version that uses generic XML code, there is no such support.

En este proyecto, se usa un solo archivo de plantilla para generar las clases que hacen posible la versión con tipo.In this project, a single template file is used to generate the classes that make the typed version possible.

Configurar el proyectoSet up the Project

Crear o abrir un proyecto en C#Create or open a C# project

Puede aplicar esta técnica a cualquier proyecto de código.You can apply this technique to any code project. En este tutorial se usa un proyecto de C#, mientras que para la realización de las pruebas se usa una aplicación de consola.This walkthrough uses a C# project, and for the purposes of testing we use a console application.

  1. En el menú Archivo , haga clic en Nuevo y, después, haga clic en Proyecto.On the File menu click New and then click Project.

  2. Haga clic en el nodo Visual C# y, en el panel Plantillas , haga clic en Aplicación de consola.Click the Visual C# node, and then in the Templates pane, click Console Application.

Agregar un archivo XML de prototipo al proyectoAdd a prototype XML file to the project

El propósito de este archivo es proporcionar ejemplos de los tipos de nodo XML que quiere que lea su aplicación.The purpose of this file is to provide samples of the XML node types that you want your application to be able to read. Puede ser un archivo que se usará para probar la aplicación.It could be a file that will be used for testing your application. La plantilla producirá una clase de C# para cada tipo de nodo de este archivo.The template will produce a C# class for each node type in this file.

El archivo debe formar parte del proyecto para que la plantilla pueda leerlo, pero no se integrará en la aplicación compilada.The file should be part of the project so that the template can read it, but it will not be built into the compiled application.

  1. En el Explorador de soluciones, haga clic con el botón derecho en el proyecto, haga clic en Agregar y después en Nuevo elemento.In Solution Explorer, right-click the project, click Add and then Click New Item.

  2. En el cuadro de diálogo Agregar nuevo elemento , seleccione Archivo XML en el panel Plantillas .In the Add New Item dialog box, select XML File from the Templates pane.

  3. Agregue el contenido de ejemplo al archivo.Add your sample content to the file.

  4. Para este tutorial, asigne al archivo el nombre exampleXml.xml.For this walkthrough, name the file exampleXml.xml. Establezca el contenido del archivo de modo que sea el XML que se muestra en la sección anterior.Set the content of the file to be the XML shown in the previous section.

Agregar un archivo de código de pruebaAdd a test code file

Agregue un archivo de C# al proyecto y escriba en él un ejemplo del código que quiere poder escribir.Add a C# file to your project and write in it a sample of the code that you want to be able to write. Por ejemplo:For example:

using System;
namespace MyProject
{
  class CodeGeneratorTest
  {
    public void TestMethod()
    {
      Catalog catalog = new Catalog(@"..\..\exampleXml.xml");
      foreach (Artist artist in catalog.Artist)
      {
        Console.WriteLine(artist.name);
        foreach (Song song in artist.Song)
        {
          Console.WriteLine("   " + song.Text);
} } } } }

En esta fase, este código no se compila.At this stage, this code will fail to compile. A medida que escribe la plantilla, generará las clases que permiten que se compile correctamente.As you write the template, you will generate classes that allow it to succeed.

Una prueba más completa podría comprobar la salida de esta función de prueba con el contenido conocido del archivo XML de ejemplo.A more comprehensive test could check the output of this test function against the known content of the example XML file. Pero, en este tutorial, nos basta con que el método de prueba se compile.But in this walkthrough, we will be satisfied when the test method compiles.

Agregar un archivo de plantilla de textoAdd a text template file

Agregue un archivo de plantilla de texto y establezca la extensión de salida .cs.Add a text template file, and set the output extension to .cs.

  1. En el Explorador de soluciones, haga clic con el botón derecho en el proyecto, haga clic en Agregary después en Nuevo elemento.In Solution Explorer, right-click the project, click Add, and then click New Item.

  2. En el cuadro de diálogo Agregar nuevo elemento , seleccione Plantilla de texto en el panel Plantillas .In the Add New Item dialog box select Text Template from the Templates pane.

    Nota

    Asegúrese de agregar una plantilla de texto y no una plantilla de texto preprocesada.Make sure that you add a Text Template, and not a Preprocessed Text Template.

  3. En la directiva de plantilla del archivo, cambie el atributo hostspecific a true.In the file, in the template directive, change the hostspecific attribute to true.

    Este cambio permitirá que el código de plantilla obtenga acceso a los servicios de Programa para la mejoraVisual Studio .This change will enable the template code to gain access to the Programa para la mejoraVisual Studio services.

  4. En la directiva de salida, cambie el atributo de extensión a ".cs" para que la plantilla genere un archivo de C#.In the output directive, change the extension attribute to ".cs", so that the template generates a C# file. En un proyecto de Visual Basic, lo cambiaría a ".vb".In a Visual Basic project, you would change it to ".vb".

  5. Guarde el archivo.Save the file. En esta fase, el archivo de plantilla de texto debe contener estas líneas:At this stage, the text template file should contain these lines:

    <#@ template debug="false" hostspecific="true" language="C#" #>
    <#@ output extension=".cs" #>
    

Observe que aparece un archivo .cs en el Explorador de soluciones como subsidiario del archivo de plantilla.Notice that a .cs file appears in Solution Explorer as a subsidiary of the template file. Puede verlo haciendo clic en [+] junto al nombre del archivo de plantilla.You can see it by clicking [+] next to the name of the template file. Este archivo se genera a partir del archivo de plantilla cada vez que guarde o mueva el foco fuera del archivo de plantilla.This file is generated from the template file whenever you save or move the focus away from the template file. El archivo generado se compilará como parte de su proyecto.The generated file will be compiled as part of your project.

Para mayor comodidad mientras desarrolla el archivo de plantilla, organice las ventanas del archivo de plantilla y del archivo generado de modo que pueda verlos uno al lado del otro.For convenience while you develop the template file, arrange the windows of the template file and the generated file so that you can see them next to each other. Esto le permite ver inmediatamente la salida de la plantilla.This lets you see immediately the output of your template. También observará que, cuando la plantilla genere código de C# no válido, aparecerán errores en la ventana de mensajes de error.You will also notice that when your template generates invalid C# code, errors will appear in the error message window.

Las modificaciones que realice directamente en el archivo generado se perderán cuando guarde el archivo de plantilla.Any edits you perform directly in the generated file will be lost whenever you save the template file. Por eso, debe evitar modificar el archivo generado, o editarlo solo para realizar breves experimentos.You should therefore either avoid editing the generated file, or edit it only for short experiments. A veces resulta útil probar un fragmento corto de código en el archivo generado donde IntelliSense esté en funcionamiento y, después, copiarlo en el archivo de plantilla.It is sometimes useful to try a short fragment of code in the generated file, where IntelliSense is in operation, and then copy it to the template file.

Desarrollar la plantilla de textoDevelop the Text Template

Siguiendo las recomendaciones para un desarrollo ágil, desarrollaremos la plantilla en pasos pequeños, eliminando algunos errores en cada incremento, hasta que el código de prueba se compile y se ejecute correctamente.Following the best advice on agile development, we will develop the template in small steps, clearing some of the errors at each increment, until the test code compiles and runs correctly.

Crear un prototipo del código que se va a generarPrototype the code to be generated

El código de prueba requiere una clase para cada nodo del archivo.The test code requires a class for each node in the file. Por lo tanto, algunos de los errores de compilación desaparecerán si anexa estas líneas a la plantilla y después la guarda:Therefore, some of the compilation errors will go away if you append these lines to the template, and then save it:

class Catalog {}
class Artist {}
class Song {}

Esto le ayuda a ver lo que es necesario, pero las declaraciones se deben generar a partir de los tipos de nodo del archivo XML de ejemplo.This helps you see what is required, but the declarations should be generated from the node types in the sample XML file. Elimine estas líneas experimentales de la plantilla.Delete these experimental lines from the template.

Generar código de aplicación a partir del archivo XML del modeloGenerate application code from the model XML file

Para leer el archivo XML y generar declaraciones de clase, reemplace el contenido de la plantilla por el siguiente código de plantilla:To read the XML file and generate class declarations, replace the template content with the following template code:

<#@ template debug="false" hostspecific="true" language="C#" #>
<#@ output extension=".cs" #>
<#@ assembly name="System.Xml"#>
<#@ import namespace="System.Xml" #>
<#
 XmlDocument doc = new XmlDocument();
 // Replace this file path with yours:
 doc.Load(@"C:\MySolution\MyProject\exampleXml.xml");
 foreach (XmlNode node in doc.SelectNodes("//*"))
 {
#>
  public partial class <#= node.Name #> {}
<#
 }
#>

Reemplace la ruta de acceso del archivo por la ruta de acceso correcta para su proyecto.Replace the file path with the correct path for your project.

Observe los delimitadores de bloque de código <#...#>.Notice the code block delimiters <#...#>. Estos delimitadores separan un fragmento del código de programa que genera el texto.These delimiters bracket a fragment of the program code that generates the text. Los delimitadores de bloque de expresión <#=...#> separan una expresión que se puede evaluar como una cadena.The expression block delimiters <#=...#> bracket an expression that can be evaluated to a string.

Cuando escribe una plantilla que genera código fuente para la aplicación, está tratando con dos textos de programas independientes.When you are writing a template that generates source code for your application, you are dealing with two separate program texts. El programa incluido dentro de los delimitadores de bloque de código se ejecuta cada vez que se guarda la plantilla o se mueve el foco a otra ventana.The program inside the code block delimiters runs every time that you save the template or move the focus to another window. El texto que genera, que aparece fuera de los delimitadores, se copia en el archivo generado y pasa a formar parte del código de aplicación.The text that it generates, which appears outside the delimiters, is copied to the generated file and becomes part of your application code.

La directiva <#@assembly#> se comporta como una referencia, lo que hace que el ensamblado esté disponible para el código de plantilla.The <#@assembly#> directive behaves like a reference, making the assembly available to the template code. La lista de ensamblados que la plantilla ve es independiente de la lista de referencias en el proyecto de aplicación.The list of assemblies seen by the template is separate from the list of References in the application project.

La directiva <#@import#> actúa como una instrucción using , lo que permite usar los nombres cortos de las clases del espacio de nombres importado.The <#@import#> directive acts like a using statement, allowing you to use the short names of classes in the imported namespace.

Desgraciadamente, aunque esta plantilla genera código, produce una declaración de clase para cada nodo del archivo XML de ejemplo, por lo que si hay varias instancias del nodo <song> , aparecerán varias declaraciones de la clase song.Unfortunately, although this template generates code, it produces a class declaration for every node in the example XML file, so that if there are several instances of the <song> node, several declarations of the class song will appear.

Leer el archivo de modelo y después generar el códigoRead the model file, then generate the code

Muchas plantillas de texto siguen un patrón según el cual la primera parte de la plantilla lee el archivo de origen y la segunda parte genera la plantilla.Many text templates follow a pattern in which the first part of the template reads the source file, and the second part generates the template. Necesitamos leer todo el archivo de ejemplo para resumir los tipos de nodo que contiene y luego generar las declaraciones de clase.We need to read all of the example file to summarize the node types that it contains, and then generate the class declarations. Hace falta otra directiva <#@import#> para que podemos usar Dictionary<>:Another <#@import#> is needed so that we can use Dictionary<>:

<#@ template debug="false" hostspecific="true" language="C#" #>
<#@ output extension=".cs" #>
<#@ assembly name="System.Xml"#>
<#@ import namespace="System.Xml" #>
<#@ import namespace="System.Collections.Generic" #>
<#
 // Read the model file
 XmlDocument doc = new XmlDocument();
 doc.Load(@"C:\MySolution\MyProject\exampleXml.xml");
 Dictionary <string, string> nodeTypes =
        new Dictionary<string, string>();
 foreach (XmlNode node in doc.SelectNodes("//*"))
 {
   nodeTypes[node.Name] = "";
 }
 // Generate the code
 foreach (string nodeName in nodeTypes.Keys)
 {
#>
  public partial class <#= nodeName #> {}
<#
 }
#>

Agregar un método auxiliarAdd an auxiliary method

Un bloque de control de características de clase es un bloque en el que se pueden definir métodos auxiliares.A class feature control block is a block in which you can define auxiliary methods. El bloque se delimita con <#+...#> y debe aparecer como el último bloque del archivo.The block is delimited by <#+...#> and it must appear as the last block in the file.

Si prefiere que los nombres de clase empiecen con una letra mayúscula, puede reemplazar la última parte de la plantilla por el siguiente código de plantilla:If you prefer class names to begin with an uppercase letter, you can replace the last part of the template with the following template code:

// Generate the code
 foreach (string nodeName in nodeTypes.Keys)
 {
#>
  public partial class <#= UpperInitial(nodeName) #> {}
<#
 }
#>
<#+
 private string UpperInitial(string name)
 { return name[0].ToString().ToUpperInvariant() + name.Substring(1); }
#>

En esta fase, el generado .cs archivo contiene las declaraciones siguientes:At this stage, the generated .cs file contains the following declarations:

public partial class Catalog {}
public partial class Artist {}
public partial class Song {}

Usando este mismo enfoque se pueden agregar más detalles, como propiedades de los nodos secundarios, atributos y texto interno.More details such as properties for the child nodes, attributes, and inner text can be added using the same approach.

Obtener acceso a la API de Visual StudioAccess the Visual Studio API

Si establece el atributo hostspecific de la directiva <#@template#> , la plantilla puede tener acceso a la API de Programa para la mejoraVisual Studio .Setting the hostspecific attribute of the <#@template#> directive allows the template to obtain access to the Programa para la mejoraVisual Studio API. De este modo, la plantilla puede obtener la ubicación de los archivos de proyecto para evitar el uso de una ruta de acceso a archivo absoluta en el código de plantilla.The template can use this to obtain the location of the project files, to avoid using an absolute file path in the template code.

<#@ template debug="false" hostspecific="true" language="C#" #>
...
<#@ assembly name="EnvDTE" #>
...
EnvDTE.DTE dte = (EnvDTE.DTE) ((IServiceProvider) this.Host)
                       .GetService(typeof(EnvDTE.DTE));
// Open the prototype document.
XmlDocument doc = new XmlDocument();
doc.Load(System.IO.Path.Combine(dte.ActiveDocument.Path, "exampleXml.xml"));

Completar la plantilla de textoComplete the Text Template

El siguiente contenido de la plantilla genera código que permite compilar y ejecutar el código de prueba.The following template content generates code that allows the test code to compile and run.

<#@ template debug="false" hostspecific="true" language="C#" #>
<#@ output extension=".cs" #>
<#@ assembly name="System.Xml" #>
<#@ assembly name="EnvDTE" #>
<#@ import namespace="System.Xml" #>
<#@ import namespace="System.Collections.Generic" #>
using System;using System.Collections.Generic;using System.Linq;using System.Xml;namespace MyProject{
<#
 // Map node name --> child name --> child node type
 Dictionary<string, Dictionary<string, XmlNodeType>> nodeTypes = new Dictionary<string, Dictionary<string, XmlNodeType>>();

 // The Visual Studio host, to get the local file path.
 EnvDTE.DTE dte = (EnvDTE.DTE) ((IServiceProvider) this.Host)
                       .GetService(typeof(EnvDTE.DTE));
 // Open the prototype document.
 XmlDocument doc = new XmlDocument();
 doc.Load(System.IO.Path.Combine(dte.ActiveDocument.Path, "exampleXml.xml"));
 // Inspect all the nodes in the document.
 // The example might contain many nodes of the same type,
 // so make a dictionary of node types and their children.
 foreach (XmlNode node in doc.SelectNodes("//*"))
 {
   Dictionary<string, XmlNodeType> subs = null;
   if (!nodeTypes.TryGetValue(node.Name, out subs))
   {
     subs = new Dictionary<string, XmlNodeType>();
     nodeTypes.Add(node.Name, subs);
   }
   foreach (XmlNode child in node.ChildNodes)
   {
     subs[child.Name] = child.NodeType;
   }
   foreach (XmlNode child in node.Attributes)
   {
     subs[child.Name] = child.NodeType;
   }
 }
 // Generate a class for each node type.
 foreach (string className in nodeTypes.Keys)
 {
    // Capitalize the first character of the name.
#>
    partial class <#= UpperInitial(className) #>
    {      private XmlNode thisNode;      public <#= UpperInitial(className) #>(XmlNode node)       { thisNode = node; }

<#
    // Generate a property for each child.
    foreach (string childName in nodeTypes[className].Keys)
    {
      // Allow for different types of child.
      switch (nodeTypes[className][childName])
      {
         // Child nodes:
         case XmlNodeType.Element:
#>
      public IEnumerable<<#=UpperInitial(childName)#>><#=UpperInitial(childName) #>      {         get         {            foreach (XmlNode node in                thisNode.SelectNodes("<#=childName#>"))              yield return new <#=UpperInitial(childName)#>(node);       } }
<#
         break;
         // Child attributes:
         case XmlNodeType.Attribute:
#>
      public string <#=childName #>      { get { return thisNode.Attributes["<#=childName#>"].Value; } }
<#
         break;
         // Plain text:
         case XmlNodeType.Text:
#>
      public string Text  { get { return thisNode.InnerText; } }
<#
         break;
       } // switch
     } // foreach class child
  // End of the generated class:
#>
   }
<#
 } // foreach class

   // Add a constructor for the root class
   // that accepts an XML filename.
   string rootClassName = doc.SelectSingleNode("*").Name;
#>
   partial class <#= UpperInitial(rootClassName) #>   {      public <#= UpperInitial(rootClassName) #>(string fileName){        XmlDocument doc = new XmlDocument();        doc.Load(fileName);        thisNode = doc.SelectSingleNode("<#=rootClassName#>");}   }}
<#+
   private string UpperInitial(string name)
   {
      return name[0].ToString().ToUpperInvariant() + name.Substring(1);
   }
#>

Ejecute el programa de pruebaRun the test program

En la ventana principal de la aplicación de consola, las siguientes líneas ejecutarán el método de prueba.In the main of the console application, the following lines will execute the test method. Pulse F5 para ejecutar el programa en modo de depuración:Press F5 to run the program in debug mode:

using System;
namespace MyProject
{
  class Program
  {
    static void Main(string[] args)
    {
      new CodeGeneratorTest().TestMethod();
      // Allow user to see the output:
      Console.ReadLine();
    }
  }
}

Escribir y actualizar la aplicaciónWrite and update the application

Ahora la aplicación se puede escribir en un estilo fuertemente tipado usando las clases generadas en lugar de código XML genérico.The application can now be written in strongly-typed style, using the generated classes instead of using generic XML code.

Cuando el esquema XML cambie, se podrán generar fácilmente clases nuevas.When the XML schema changes, new classes can easily be generated. El compilador le indicará al desarrollador dónde es necesario actualizar el código de aplicación.The compiler will tell the developer where the application code must be updated.

Para volver a generar las clases cuando se cambia el archivo XML de ejemplo, haga clic en Transformar todas las plantillas en el el Explorador de soluciones barra de herramientas.To regenerate the classes when the example XML file is changed, click Transform All Templates in the Solution Explorer toolbar.

ConclusiónConclusion

En este tutorial se muestran varias técnicas y ventajas de la generación de código:This walkthrough demonstrates several techniques and benefits of code generation:

  • Lageneración de código es la creación de parte del código fuente de la aplicación a partir de un modelo.Code generation is the creation of part of the source code of your application from a model. El modelo contiene información en un formato adecuado para el dominio de aplicación y puede cambiar durante la vigencia de la aplicación.The model contains information in a form suited to the application domain, and may change over the lifetime of the application.

  • El tipado fuerte es una de las ventajas de la generación de código.Strong typing is one benefit of code generation. Aunque el modelo representa la información en un formato más adecuado para el usuario, el código generado permite que otras partes de la aplicación traten la información con un conjunto de tipos.While the model represents information in a form more suitable to the user, the generated code allows other parts of the application to deal with the information using a set of types.

  • IntelliSense y el compilador ayudan a crear código que cumple el esquema del modelo, tanto al escribir código nuevo como al actualizar el esquema.IntelliSense and the compiler help you create code that adheres to the schema of the model, both when you write new code and when the schema is updated.

  • La adición de un único archivo de plantilla poco complicado a un proyecto puede proporcionar estas ventajas.The addition of a single uncomplicated template file to a project can provide these benefits.

  • Es posible desarrollar y probar rápidamente y de manera incremental una plantilla de texto.A text template can be developed and tested rapidly and incrementally.

En este tutorial, el código de programa se genera realmente desde una instancia del modelo, que es un ejemplo representativo de los archivos XML que la aplicación va a procesar.In this walkthrough, the program code is actually generated from an instance of the model, a representative example of the XML files that the application will process. Siguiendo un enfoque más formal, el esquema XML sería la entrada a la plantilla, en forma de archivo .xsd o definición de lenguaje específico de dominio.In a more formal approach, the XML schema would be the input to the template, in the form of an .xsd file or a domain-specific language definition. Este enfoque puede facilitar que la plantilla determine características como la multiplicidad de una relación.That approach would make it easier for the template to determine characteristics such as the multiplicity of a relationship.

Solución de problemas de la plantilla de textoTroubleshoot the Text Template

Si ve errores de compilación o de transformación de la plantilla en la Lista de errores, o si el archivo de salida no se genera correctamente, puede solucionar los problemas de la plantilla de texto con las técnicas descritas en Generar archivos con la utilidad TextTransform.If you have seen template transformation or compilation errors in the Error List, or if the output file was not generated correctly, you can troubleshoot the text template with the techniques described in Generating Files with the TextTransform Utility.

Vea tambiénSee also