|
Buscador
Secciones
Registro
¡Colabora!
Ganamos
Servicios
|
Tabla 11: Secuencias de espace XML de uso frecuente
|
| Operador | Identificador |
|---|---|
| + | op_Addition |
| - | op_Substraction |
| * | op_Multiply |
| / | op_Division |
| % | op_Modulus |
| < | op_LessThan |
| > | op_GreaterThan |
| >= | op_GreaterThanOrEqual |
| <= | op_LowerThanOrEqual |
| == | op_Equality |
| != | op_Inequality |
| ! | op_LogicalNot |
| Operador | Identificador |
|---|---|
| & | op_BitwiseAnd |
| | | op_BitwiseOr |
| ^ | op_ExclusiveOr |
| ~ | op_OnesComplement |
| << | op_LeftShift |
| >> | op_RightShift |
| true | op_True |
| false | op_False |
| ++ | op_Increment |
| -- | op_Decrement |
| Conversión explícita | Op_Explict |
| Conversión implícita | Op_Implicit |
Tabla 12: Nombres dados a operadores en documentación XML
En el caso de los operadores de conversión, tras la lista de parámetros se incluye adicionalmente un carácter ~ seguido del tipo de retorno del operador.
Para que se entienda mejor la forma en que se han de dar valores a cref, a continuación se muestra un fragmento de código de ejemplo en el que junto a cada definición se ha escrito un comentario con el valor que habría que darle a cref para referenciarla:
// cref="Espacio"
namespace Espacio
{
// cref="Espacio.Clase"
class Clase
{
// cref="Espacio.Clase.Campo"
int Campo;
// cref="Espacio.Clase.Propiedad"
int Propiedad
{ set {} }
// cref="Espacio.Clase.EstructuraInterna"
struct EstructuraInterna
{}
// cref="Espacio.Clase.DelegadoInterno"
public delegate int DelegadoInterno(string s, float f);
// cref ="Espacio.Clase.Evento"
public event DelegadoInterno Evento;
// cref="Espacio.Clase.Metodo(System.Int32, System.Int32@,
// System.Int32*, System.Int32@,
// System.Int32[][], System.Int32[0:, 0:, 0:])"
int Metodo(int a, out int b, int * c, ref d, int[][] e, int[,,] f)
{return 1;}
// cref="Espacio.Clase.Item(System.String)"
int this[string s]
{ set {} }
// cref="Espacio.Clase.#ctor"
Clase(int a)
{}
// cref="Espacio.Clase.#cctor"
static Clase(int a)
{}
// cref="Espacio.Clase.Finalize"
~X()
{}
// cref="Espacio.Clase.op_Addition(Espacio.Clase, Espacio.Clase)"
public static int operator +(Clase operando1, Clase operando2)
{ return 1; }
// cref="Espacio.Clase.op_Explicit (Espacio.Clase)~System.Int32"
public static explicit operator int(Clase fuente)
{ return 1; }
}
}
En realidad no es siempre necesario usar calificación completa en el valor de cref. Si se referencia a un tipo desde la misma definición de espacio de nombres desde donde se le definió o que importa su espacio de nombres, no es necesario incluir dicho espacio en la referencia; y si se referencia a un miembro desde el el mismo tipo donde se definió, no es necesario incluir ni el nombre del tipo ni el de su espacio de nombres.
Etiquetas recomendadas
para documentación XMLAunque el programador puede utilizar las etiquetas estime oportunas en sus comentarios de documentación y darles el significado que quiera, Microsoft recomienda usar un juego de etiquetas concreto con significados concretos para escribir ciertos tipos de información común. Con ello se obtendría un conjunto básico de etiquetas que cualquier herramienta que trabaje con documentación XML pueda estar preparada para procesar (como veremos más adelante, el propio Visual Studio.NET da ciertos usos específicos a la información así documentada)
En los siguientes epígrafes se explican estas etiquetas recomendadas agrupándolas según su utilidad. Todas son opcionales, y no incluirlas sólo tiene el efecto de que no en la documentación resultante no se generarían las secciones correspondientes a ellas.
Etiquetas de uso
genéricoHay una serie de etiquetas predefinidas que pueden colocarse, en cualquier orden, precediendo las definiciones de miembros en los ficheros fuente. Estas etiquetas, junto al significado recomendado para su contenido, son las explicadas a continuación:
/// <permission cref="System.Security.Permissions.FileIOPermission"> /// Necesita permiso de lectura/escritura en el directorio C:\Datos /// </permission>
Como con <seealso>, si un miembro ha de disponer varios tipos de permisos puede documentarse su definición con tantas etiquetas <permission> como sea necesario.
Etiquetas relativas a
métodosAdemás de las etiquetas uso general ya vistas, en las definiciones de métodos se pueden usar las siguientes etiquetas recomendadas adicionales para describir sus parámetros y valor de retorno:
/// <summary> Método que muestra un texto por pantalla </summary>
/// <param name="texto"> Texto a mostrar </param>
bool MuestraTexto(string texto)
{...}
Al generarse la documentación se comprueba si el método documentado dispone de algún parámetro con el nombre indicado en name y, como ocurre con cref, si no fuese así se generaría un mensaje de aviso informando de ello.
/// <summary>
/// Método que muestra por pantalla un texto con un determinado color
/// </summary>
/// <param name="texto"> Texto a mostrar </param>
/// <param name="color">
/// Color con el que mostrar el <paramref name="texto"/> indicado
/// </param>
bool MuestraTexto(string texto, Color color)
{...}
Nuevamente, al generarse la documentación se comprobará si realmente el parámetro referenciado existe en la definición del método documentado y si no es así se generá un mensaje de aviso informando de ello.
/// <summary>
/// Método que muestra por pantalla un texto con un determinado color
/// </summary>
/// <param name="texto"> Texto a mostrar </param>
/// <param name="color">
/// Color con el que mostrar el <paramref name="texto"/> indicado
/// </param>
/// <returns> Indica si el método se ha ejecutado con éxito o no </summary>
bool MuestraTexto(string texto, Color color)
{...}
Etiquetas relativas a
propiedadesEl uso más habitual de una propiedad consiste en controlar la forma en que se accede a un campo privado, por lo que esta se comporta como si almacenase un valor. Mediante el contenido de la etiqueta <value> es posible describir el significado de ese valor:
private int edad;
/// <summary>
/// Almacena la edad de una persona. Si se le asigna una edad menor
/// que 0 la sustituye por 0.
/// </summary>
/// <value> Edad de la persona representada </value>
public int Edad
{
set { edad = (value<0)? 0:value }
get { return edad; }
}
Etiquetas relativas a
excepcionesPara documentar el significado de un tipo defindo como excepción puede incluirse un resumen sobre el mismo como contenido de una etiqueta de documentación <exception> que preceda a su definición. El atributo cref de ésta suele usarse para indicar la clase de la que deriva la excepción definida. Por ejemplo:
/// <exception cref="System.Exception">
/// Excepción de ejemplo creada por Josan
/// </exception>
class JosanExcepción: Exception
{}
Etiquetas relativas a
formatoPara mejorar la forma de expresar el contenido de las etiquetas de documentación que se utilicen es posible incluir en ellas las siguientes etiquetas de formato:
/// <summary>
/// Muestra por la salida estándar el mensaje ¡Hola!.
/// Si no sabe como se escribe en pantalla puede consultar la
/// documentación del método
/// <see cref="System.Console.WriteLine"/>.
/// </summary>
public static void Saluda()
{
Console.WriteLine("¡Hola!");
}
Nótese que la diferencia de <see> y <seealso> es que la primera se usa para indicar enlaces en medio de textos mientras que la otra se usa para indicar enlaces que se deseen incluir en una sección aparte tipo "Véase también".
En general, <code> suele usarse dentro de etiquetas <example> para mostrar fragmentos de códigos de ejemplo, mientras que <c> suele usarse para hacer referencia a elementos puntales de los códigos fuente. Por ejemplo:
/// <example> /// Este ejemplo muestra cómo llamar al método /// <c>Cumple()</c> de esta clase: /// <code> /// Persona p = new Persona(...); /// p.Cumple(); /// </code> /// </example>
/// <remarks> /// <para> /// Primer párrafo de la descripción del miembro... /// </para> /// <para> /// Segundo párrafo de la descripción del miembro... /// </para> /// </remarks>
El contenido de <list> dependerá del tipo de estructura representado en cada caso:
/// <list type="bullet"> /// <item> /// <description> /// Elemento 1 /// </description> /// </item> /// <item> /// <description> /// Elemento 2 /// </description> /// </item> /// </list>
Además, opcionalmente se podría incluir una etiqueta <listheader> antes de las etiquetas <item> donde se indicaría cuál ha de ser el texto de la cabecera de la tabla. Esta etiqueta se usa igual que las etiquetas <item>: incluirá una etiqueta <description> por cada columna.
/// <list type="bullet"> /// <item> /// <term> /// Término 1 /// </term> /// <description> /// Descripción de término 1 /// </description> /// </item> /// <item> /// <term> /// Término 2 /// </term> /// <description> /// Descripción de término 2 /// </description> /// </item> /// </list>
Generación de
documentación XML
Generación a
través del compilador en línea de comandosUsando el compilador en línea de comandos puede generarse documentación sobre los tipos definidos en los fuentes a compilar usando la opción de compilación /doc:<fichero>. Por ejemplo, para compilar un fichero de código fuente Persona.cs y generar su documentación en Persona.xml, habría que llamar al compilador con:
csc persona.cs /doc:persona.xml
Si se abre con Internet Explorer el fichero XML así generado se verá un conjunto de etiquetas que recogen toda la información ubicada en los comentarios de documentación de los fuentes compilados. Aunque para una persona pueda resultar difícil leer esta información, para una aplicación hacerlo es muy sencillo a través de un analizador XML. Si se dese que también sea legible para humanos basta abrirlo con cualquier editor de textos y añadirle una primera línea de la forma:
<?xml:stylesheet href="<ficheroXSL>" type="text/xsl"?>
Con esta línea se indica que se desea utilizar el fichero indicado en <ficheroXSL> como hoja de estilo XSL con la que convertir la documentación XML a algún lenguaje más fácilmente legible por humanos (generalmente, HTML). Por ejemplo, si doc.xsl es el nombre de dicho fichero XSL, bastaría escribir:
<?xml:stylesheet href="doc.xsl" type="text/xsl"?>
Para hacerse una idea de las diferencias existentes entre abrir con Internet Explorer un fichero de documentación sin hoja XSL asociada y abrir ese mismo fichero pero asociándole una hoja XSL, puede observar las siguientes ilustraciones:


No se preocupe si no sabe escribir hojas de estilo, pues como se explica en el siguiente epígrafe, Visual Studio.NET incluye una herramienta que puede generar directamente la documentación en un HTML fácilmente legible para humanos.
Generación a
través de Visual Studio.NETSi prefiere usar Visual Studio.NET, entonces para la generación de la documentación basta señalar el proyecto a documentar en el Solution Explorer y escribir el nombre del fichero XML a generar en el cuadro de texto View -> Property Pages -> Configuration Properties -> Build -> XML Documentation File
Cuando se compile el proyecto, la documentación XML sobre el mismo se guardará en el fichero indicado en el cuadro de texto anterior. Este fichero se almacenará dentro de la subcarpeta Bin del directorio del proyecto, y si se desea poder visualizarla desde el Solution Explorer hay que activar en éste el botón Show All Files.
En principio, para conseguir visualizar esta documentación en un formato más legible para humanos podría asociársele una hoja XSL como se explicó para el caso del compilador en línea de comandos. Sin embargo, Visual Studio.NET proporciona una forma más sencilla de hacerlo a través de la herramienta ubicada en Tools -> Build Comments Web Pages Esta utilidad a partir de la información incluida en las etiquetas recomendadas de los comentarios del fuente genera páginas HTML que muestran la documentación del proyecto de una forma vistosa e intuitiva (ver Ilustración)

Estructura de la
documentación XMLAhora que ya sabemos cómo escribir comentarios de documentación y generar a partir de ellos un fichero XML con la documentación de los tipos de datos de un fichero, sólo queda estudiar cuál es concretamente la estructura de dicho fichero generado ya que entenderla es fundamental para la escritura de aplicaciones encargadas de procesarlo.
En principio, si compilamos como módulo un fuente sin comentarios de documentación pero solicitando la generación de documentación, se obtendrá el siguiente fichero XML:
<?xml version="1.0"?> <doc> <members> </members> </doc>
Como se ve, la primera línea del fichero es la cabecera típica de todo fichero XML en la que se indica cuál es la versión del lenguaje que utiliza. Tras ella se coloca una etiqueta <doc> que contendrá toda la documentación generada, y los comentarios de documentación de los miembros del fuente compilado se irían incluyendo dentro de la etiqueta <members> que contiene (en este caso dicha etiqueta está vacía ya que el fuente compilado carecía de comentarios de documentación)
Si hubiésemos compilado el fuente como librería o como ejecutable se habría generado un ensamblado, y a la estructura anterior se le añadiría una etiqueta adicional dentro de <doc> con información sobre el mismo, quedando:
<?xml version="1.0"?>
<doc>
<assembly>
<name>Persona</name>
</assembly>
<members>
</members>
</doc>
Como se ve, dentro de la etiqueta <assembly> contenida en <doc> se indican las características del ensamblado generado. En concreto, su nombre se indica en la etiqueta <name> que contiene (se supone que el ensamblado se compiló con el nombre Persona)
Si ahora le añadimos comentarios de documentación veremos que el contenido de estos se inserta dentro de la etiqueta <members>, en una etiqueta <member> específica para cada miembro con comentarios de documentación. Por ejemplo, dado el fuente:
/// <summary>
/// Clase de ejemplo de cómo escribir documentacion XML
/// </summary>
class A
{
/// <summary>
/// Método principal de ejemplo perteneciente a clase <see cref="A"/>
/// </summary>
/// <remarks>
/// No hace nada
/// </remarks>
static void Main()
{}
}
La documentación XML que generara compilarlo con la opción /doc es:
<?xml version="1.0"?>
<doc>
<assembly>
<name>A</name>
</assembly>
<members>
<member name="T:A">
<summary>
Clase de ejemplo de cómo escribir documentacion XML
</summary>
</member>
<member name="M:A.Main">
<summary>
Método principal de ejemplo perteneciente a clase <see cref="T:A"/>
</summary>
<remarks>
No hace nada
</remarks>
</member>
</members>
</doc>
Como puede verse, dentro de la etiqueta <members> no se sigue ninguna estructura jerárquica a la hora de describir los elementos del fuente, sino que todos se describen al mismo nivel y de la misma forma: se incluye una etiqueta <member> por cada miembro documentado en cuyo atributo name se indica su nombre y en cuyo contenido se inserta el texto de sus comentarios de documentación.
Nótese que a cada elemento se le da en el atributo name de su etiqueta <member> correspondiente un identificador que lo distingue unívocamente del resto de miembros documentados y que sigue la siguiente sintaxis:
<indicadorElemento>:<nombreCompletamenteCalificado>
El <indicadorElemento> es simplemente un carácter que indica qué tipo de elemento se documenta dentro de la etiqueta <member>. Puede tomar estos valores:
| Indicador de tipo de elemento | Tipo de elemento indicado |
|---|---|
| T | Tipo de dato |
| F | Campo |
| P | Propiedad o indizador |
| M | Método (incluidos operadores y contructores) |
| E | Evento |
Tabla 13: Indicadores de tipos de elementos en documentaciones XML
Como se ve en el ejemplo, en la documentación generada se usa también la sintaxis de los valores del atributo name de las etiquetas <member> para representar las referencias mediante atributos cref. Además, cuando dicha sintaxis se usa para expresar valores de cref pueden usarse dos tipos de indicadores más:
| Indicador de tipo de elemento | Tipo de elemento indicado |
| N | Espacio de nombres |
| ! | Ninguno. Se genera cuando el miembro indicado en cref no existe. |
Tabla 14: Indicadores de tipos de elementos para atributos cref
La idea que hay detrás de usar la sintaxis vista para representar elementos del fuente es proporcinar un mecanismo sencillo mediante el que las herramientas encargadas de procesar las documentaciones XML puedan determinar cuáles son los miembros documentados o referenciados y acceder, con ayuda de los tipos de System.Reflection, a sus metadatos asociados.
Separación entre
documentación XML y código fuenteA veces puede que interesar incrustar toda la documentación en el mismo fichero que el código fuente, por ejemplo si se desea reusarla en múltiples fuentes o si es muy voluminosa e incluirla en el fuente dificultaría su legibilidad. Para estos casos se da la posiblidad de dejar la documentación en un fichero XML aparte y referenciarla en el código fuente a través de la etiqueta de documentación <include>, que su usa así:
<include file="<nombreFichero>" path="<rutaDocumentación>"/>
Cuando el compilador encuentre esta etiqueta al generar la documentación lo que hará será tratarla como si fuese la etiqueta del fichero <nombreFichero> indicada por la expresión XPath <rutaDocumentación> Por ejemplo, si se tiene el código:
/// <include file="otro.xml" path="Miembros/Miembro[@nombre="A"]/*"/>
class A
{}
En este uso de <include> se está indicando que se ha de insertar todo el contenido de la etiqueta <Miembro> contenida en <Miembros> cuyo atributo nombre valga A. Luego, si el contenido del fichero otro.xml es de la forma:
<Miembros>
...
<Miembro name="A">
<remarks>
Ejemplo de inclusión de documentación XML externa
</remarks>
<example>
Para crear un objeto de esta clase usar:
<code>
A obj = new A();
</code>
</example>
</Miembro>
...
</Miembros>
Entonces, el compilador generará documentación como si el fuente contuviese::
/// <remarks>
/// Ejemplo de inclusión de documentación XML externa
/// </remarks>
/// <example>
/// Para crear un objeto de esta clase usar:
/// <code>
/// A obj = new A();
/// </code>
/// </example>
class A
{}
| Leer comentarios (150) | |
| Escribir comentario | |
| Puntuación: |
|
| Votar | |
| Recomendar este tutorial | |
| Estadísticas |
Copyright © 1999-2006
Programación en castellano.
Todos los derechos reservados.
Formulario de Contacto -
Datos legales -
Publicidad
Hospedaje web y servidores dedicados linux por
Ferca Network