0% encontró este documento útil (0 votos)
201 vistas118 páginas

XML

Apuntes sobre XML

Cargado por

fvalero5277
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd
0% encontró este documento útil (0 votos)
201 vistas118 páginas

XML

Apuntes sobre XML

Cargado por

fvalero5277
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd
Está en la página 1/ 118

XML

© Fernando Berzal Galiano & Francisco Cortijo Bon

XML

Esquemas XML

XML en Visual Studio .NET

Presentación y transformación de documentos XML

XML en la plataforma .NET

XML - Página 1
XML
© Fernando Berzal Galiano & Francisco Cortijo Bon

¿Qué es XML?

Sintaxis de XML
Documentos XML bien formados

Espacios de nombres

Tecnologías relacionadas

XML - Página 1
¿Qué es XML?

XML es el acrónimo de eXtensibe Markup Languaje. XML es un formato estándar del World
Wide Web Consortium (W3C) diseñado a partir de SGML para representar datos
estructurados de forma jerárquica (en un árbol). Los documentos XML incluyen una serie de
etiquetas que permiten crear documentos autocontenidos, en los que los datos van siempre
acompañados de sus metadatos correspondientes.

XML no es, como su nombre puede sugerir, un lenguaje de marcado. XML es un


metalenguaje que permite definir lenguajes de marcado adecuados a usos específicos. Aunque
a primera vista un docuento XML puede parecer similar a HTML hay una diferencia
fundamental: un documento XML contiene datos que se autodefinen, exclusivamente. Un
documento HTML contiene datos mal definidos, mezclados con elementos de formato. En
XML se separa el contenido de la presentación de forma total.

XML, al que algunos consideran el Esperanto de los sistemas de información, se emplea


principalmente para representar documentos (texto con etiquetas que identifican porciones del
documento, como es el caso de estos apuntes) y conjuntos de datos (estructuras de datos
jerárquicas, para ser más precisos).

Entre sus ventajas se encuentra su aceptación casi universal, su legibilidad y su carácter


autocontenido (a diferencia de los formatos binarios propios de cada aplicación), si bien el
tamaño de los documentos XML es mayor que el de sus equivalentes binarios y su
procesamiento requiere más recursos, por lo que no resulta adecuado en aplicaciones en las
que la eficiencia sea un objetivo prioritario.

XML - Página 2
En resumen, XML permite representar datos de forma homogénea en entornos heterogéneos,
lo que facilita la interoperabilidad entre distintos sistemas. Además, hoy en día goza de gran
popularidad, pues todas las grandes empresas promueven su utilización y se han desarrollado
numerosas tecnologías basadas en este formato estándar (SOAP, ebXML, BizTalk,
WebSphere, etc.).

Un pequeño ejemplo
Representación de datos en formato ASCII (antes de que existiese XML):

"PO-1234","CUST001","X9876","5","14.98"
Representación de los mismos datos en XML:

<ORDEN_PEDIDO>
<COD__PEDIDO> PO-1234 </COD_PEDIDO>
<COD_CLIENTE> CUST001 </COD_CLIENTE>
<COD_ARTICULO> X9876 </ITEM_NUM>
<CANTIDAD> 5 </CANTIDAD>
<PRECIO> 14.98 </PRECIO>
</ORDEN_PEDIDO>

XML - Página 3
Sintaxis de XML

Antes de nada hay que resaltar que XML es sensible a las mayúsculas.

Elementos

Los elementos XML están delimitados por etiquetas de comienzo y fin entre las que se
escribe su contenido:

<TAG_NAME> ... </TAG_NAME>

También pueden estar vacíos (elementos sin contenido):

<TAG_NAME />
La primera línea es correcta en HTML, no en XML. La segunda si lo es:

<LI>Esto es HTML<BR> que es muy permisivo.</LI>


<LI>XML es <BR/> mucho más restrictivo.</LI>
El contenido de un elemento puede ser complejo: un elemento puede contener a otros
elementos.

Atributos

XML - Página 4
Los distintos elementos de un documento XML pueden incluir atributos que describen al
elemento en cuestión (tipo de datos, dominio de valores permitidos, etc.). Dichos atributos
han de aparecer en la etiqueta de comienzo del elemento y el valor del atributo debe
especificarse entre comillas dobles (") o simples ('):

<TAG_NAME ATTRIBUTE="value"> ... </TAG_NAME>


Instrucciones de procesamiento

En su prólogo, un documento XML puede incluir una serie de instrucciones de


procesamiento, delimitadas por: <? ... ?>, en las que se puede indicar el sistema de
codificación empleado (Unicode por defecto), especificar la hoja de estilo XSLT que se
empleará para visualizar el documento, declarar espacios de nombres y definir el esquema del
documento, etc. Solo se requiere, obligatoriamente, especificar que se trata de un documento
XML:

<?xml version="1.0"?>
Un ejemplo más detallado en el que se especifica la hoja de estilo que se aplica al documento
para su presentación es el siguiente:

<?xml version="1.0" encoding="utf-8"?>


<?xml-stylesheet type="text/xsl" href="template.xsl"?>
<ROOT>
<ELEMENT1> <SUBELEMENT1 /> <SUBELEMENT2 /> </ELEMENT1>
<ELEMENT2> </ELEMENT2>
<ELEMENT3 type="string"> </ELEMENT3>
<ELEMENT4 type="integer" value="9.3"> </ELEMENT4>
</ROOT>
Entidades

Las entidades en XML proporcionan un mecanismo de substitución textual:

Entidad Sustitución
&lt; <
&gt; >
&amp; &
&apos; '
&quot; "
XML permite que se puedan definir nuevas entidades. Algunas (parsed entities) pueden
contener texto y etiquetas XML, mientras que otras (unparsed entities) sirven para almacenar

XML - Página 5
cualquier tipo de datos (imágenes, sonidos...).

Entidades predefinidas

<!ENTITY lt "&#38;#60;">
<!ENTITY gt "&#62;">
<!ENTITY amp "&#38;#38;">
<!ENTITY apos "&#39;">
<!ENTITY quot "&#34;">
Comentarios y secciones CDATA

Finalmente, un documento XML también puede incluir comentarios, delimitados por las
construcciones <!-- y --> (exactamente igual que en HTML) y secciones CDATA que
sirven para incluir cualquier cosa (contenido textual) en el documento XML, delimitadas por
las construcciones <![CDATA[ y ]]> (como <PRE> ... </PRE> en HTML).

<!-- Esto es un comentario -->


<!-- Este codigo XML no usa CDATA -->
<ejemplo>
&lt;HTML>
&lt;HEAD>
&lt;TITULO>Rock &amp; Roll&lt;/TITULO>
&lt;/HEAD>
&lt;/HTML>
</ejemplo>

<!-- Este codigo XML usa CDATA -->


<ejemplo>
<![CDATA[
<HTML>
<HEAD>
<TITULO>Rock & Roll</TITULO>
</HEAD>
</HTML>
]]>
</ejemplo>

Documentos XML bien formados


Un documento bien formado en XML tiene que reunir las siguientes cualidades:
- Debe haber un y sólo un elemento raíz.

XML - Página 6
- Los subelementos deben estar adecuadamente anidados. Esto es, un elemento ha
de terminar con la misma etiqueta con la que comenzó.

- Los atributos son opcionales (y se definen en un esquema que también es


opcional).

- Los valores de los atributos han de estar delimitados por comillas dobles (") o
comillas simples (').

- Las instrucciones de procesamiento son opcionales.

- XML es sensible a mayúsculas y minúsculas. Es decir, <tag> y <TAG> no hacen


referencia al mismo tipo de elemento.

Teniendo en cuenta las estrictas reglas anteriores, el siguiente documento XML no es válido
porque sus elementos no están anidados correctamente:

<?xml Version="1.0" ?>


<PARENT>
<CHILD1> Child 1 </CHILD1>
<CHILD2> <CHILD3> Child 3 or 2? </CHILD2> </CHILD3>
</PARENT>
El siguiente documento XML tampoco es válido porque tiene dos raíces:

<?xml Version="1.0" ?>


<PARENT>
<CHILD1> Elemento CHILD1 </CHILD1>
</PARENT>
<PARENT>
<CHILD1> Otro elemento CHILD1 </CHILD1>
</PARENT>
Sin embargo, el siguiente documento XML sí que es válido:

<?xml Version="1.0" ?>


<PARENT>
<CHILD1>Elemento CHILD1</CHILD1>
<CHILD2/>
<CHILD3> </CHILD3>
</PARENT>

Un documento XML

<?xml version='1.0' encoding="utf-8"?>


<Libreria>
<Libro Genero='Poesía' FechaPublicacion='1932'

XML - Página 7
Un documento XML
ISBN='1-861003-11-0>
<Titulo>Poeta en Nueva York</Titulo>
<Autor>
<Nombre>Federico</Nombre>
<Apellido>García Lorca</Apellido>
</Autor>
<Precio>8.99</Precio>
</Libro>
<Libro Genero='Novela' FechaPublicacion='1967'
ISBN='0-201-63361-2'>
<Titulo>The Confidence Man</Titulo>
<Autor>
<Nombre>Herman</Nombre>
<Apellido>Melville</Apellido>
</Autor>
<Precio>11.99</Precio>
</Libro>
</Libreria>

XML - Página 8
Espacios de nombres

Los espacios de nombres (namespaces) permiten que XML sea extensible, permitiendo
diferencias entre etiquetas con el mismo nombre utilizando prefijos. De esta forma se pueden
evitar conflictos de nombres y el que diseña un documento XML puede centrarse en los datos
que tiene y cómo describirlos mejor. Además, el uso de identificadores universales URI
(Uniform Resource Identifier) para hacer referencia a estándares ampliamente aceptados
permite que se puedan combinar documentos escritos independientemente.

Sintaxis

xmlns: prefijo = URI


- URI es el nombre del espacio de nombres. Cuando se usa un URL no tiene
porqué hacer referencia a un servidor activo.

- prefijo es el identificador por el que nos referimos en el documento actual,


usándolo como prefijo, a los elementos del espacio de nombres al que se refiere.

Ejemplos de declaración de namespaces

xmlns: bk = "http://www.example.com/bookinfo/"
xmlns: bk = "urn:mybookstuff.org:bookinfo"

Ejemplos de uso de namespaces

<LIBRO xmlns:bk="http://www.bookstuff.org/bookinfo">
<bk:TITULO>All About XML</bk:TITULO>
<bk:AUTOR>Joe Developer</bk:AUTOR>
<bk:PRECIO currency='US Dollar'>19.99</bk:PRECIO>
</LIBRO>

<bk:LIBRO xmlns:bk="http://www.bookstuff.org/bookinfo"
xmlns:money="urn:finance:money">
<bk:TITULO>All About XML</bk:TITULO>
<bk:AUTOR>Joe Developer</bk:AUTOR>
<bk:PRECIO money:currency='US Dollar'>19.99</bk:PRECIO>
</bk:LIBRO>
Combinar datos XML de distintas fuentes puede producir conflictos en los nombres de los
elementos y/o atributos. Supongamos que disponemos del siguiente fichero XML con nuestra
colección de libros:

XML - Página 9
libros.xml

<?xml version="1.0"?>
<COLECCION>
<ITEM Estado="in">
<TITULO>The Adventures of Huckleberry Finn</TITULO>
<AUTOR>Mark Twain</AUTOR>
<PRECIO>$5.49</PRECIO>
</ITEM>
<ITEM Estado="out">
<TITULO>Leaves of Grass</TITULO>
<AUTOR>Walt Whitman</AUTOR>
<PRECIO>$7.75</PRECIO>
</ITEM>
<ITEM Estado="out">
<TITULO>The Legend of Sleepy Hollow</TITULO>
<AUTOR>Washington Irving</AUTOR>
<PRECIO>$2.95</PRECIO>
</ITEM>
<ITEM Estado="in">
<TITULO>The Marble Faun</TITULO>
<AUTOR>Nathaniel Hawthorne</AUTOR>
<PRECIO>$10.95</PRECIO>
</ITEM>
</COLECCION>

y del siguiente con nuestra colección de discos:

discos.xml

<?xml version="1.0"?>
<COLECCION>
<ITEM>
<TITULO>Violin Concerto in D</TITULO>
<COMPOSITOR>Beethoven</COMPOSITOR>
<PRECIO>$14.95</PRECIO>
</ITEM>
<ITEM>
<TITULO>Violin Concertos Numbers 1, 2, and 3</TITULO>
<COMPOSITOR>Mozart</COMPOSITOR>
<PRECIO>$16.49</PRECIO>
</ITEM>
</COLECCION>

Queremos combinar estos documentos en uno solo, y además, queremos gestionarlo con una
sola aplicación. El problema surge al haber elementos repetidos (con el mismo nombre). Por
ejemplo, ¿Cómo hacer una lista de todos los libros? ¿Cómo calcular e precio medio de los
CDs? El mecanismo de los espacios de nombres facilita esta tarea: basta con definir un
espacio de nombres para diferenciar cada elemento. En el documento combinado cada
elemento de un libro (ITEM, TITULO, AUTOR y PRECIO) se asigna al espacio de nombres
book y cada uno de los elementos de un CD (ITEM, TITULO, COMPOSITOR y PRECIO) se

XML - Página 10
asigna al espacio de nombres cd.

Coleccion.xml

<?xml version="1.0"?>
<!-- Fichero: Coleccion.xml -->
<COLLECTION
xmlns:book="http://www.mjyOnline.com/books"
xmlns:cd="http://www.mjyOnline.com/cds">
<book:ITEM Estado="in">
<book:TITULO>
The Adventures of Huckleberry Finn
</book:TITULO>
<book:AUTOR>Mark Twain</book:AUTOR>
<book:PRECIO>$5.49</book:PRECIO>
</book:ITEM>
<cd:ITEM>
<cd:TITULO>Violin Concerto in D</cd:TITULO>
<cd:COMPOSITOR>Beethoven</cd:COMPOSITOR>
<cd:PRECIO>$14.95</cd:PRECIO>
</cd:ITEM>
<book:ITEM Estado="out">
<book:TITULO>Leaves of Grass</book:TITULO>
<book:AUTOR>Walt Whitman</book:AUTOR>
<book:PRECIO>$7.75</book:PRECIO>
</book:ITEM>
<cd:ITEM>
<cd:TITULO>
Violin Concertos Numbers 1, 2, and 3
</cd:TITULO>
<cd:COMPOSER>Mozart</cd:COMPOSER>
<cd:PRECIO>$16.49</cd:PRECIO>
</cd:ITEM>
<book:ITEM Estado="out">
<book:TITULO>
The Legend of Sleepy Hollow
</book:TITULO>
<book:AUTOR>Washington Irving</book:AUTOR>
<book:PRECIO>$2.95</book:PRECIO>
</book:ITEM>
<book:ITEM Estado="in">
<book:TITULO>The Marble Faun</book:TITULO>
<book:AUTOR>Nathaniel Hawthorne</book:AUTOR>
<book:PRECIO>$10.95</book:PRECIO>
</book:ITEM>
</COLLECTION>

Namespaces por defecto


Un espacio de nombres XML declarado sin prefijo se convierte en el espacio de nombres por
defecto para todos los subelementos del elemento en el que aparece la declaración. En esta

XML - Página 11
situación, todos los elementos que aparezcan sin prefijo harán referencia al espacio de
nombres por defecto.

Ejemplo de uso de namespaces por defecto

<LIBRO xmlns="http://www.bookstuff.org/bookinfo">
<TITULO>All About XML</TITULO>
<AUTOR>Joe Developer</AUTOR>
</LIBRO>
En el siguiente ejemplo el espacio de nombres por defecto es
http://www.mjyOnline.com/books ya que no se indica ningún prefijo en su
declaración.

Default.xml

<?xml version="1.0"?>
<!-- File Name: Default.xml -->
<COLECCION
xmlns="http://www.mjyOnline.com/books"
xmlns:cd="http://www.mjyOnline.com/cds">
<ITEM Estado="in">
<TITULO>
The Adventures of Huckleberry Finn
</TITULO>
<AUTOR>Mark Twain</AUTOR>
<PRECIO>$5.49</PRECIO>
</ITEM>
<cd:ITEM>
<cd:TITULO>Violin Concerto in D</cd:TITULO>
<cd:COMPOSER>Beethoven</cd:COMPOSER>
<cd:PRECIO>$14.95</cd:PRECIO>
</cd:ITEM>
<ITEM Estado="out">
<TITULO>Leaves of Grass</TITULO>
<AUTOR>Walt Whitman</AUTOR>
<PRECIO>$7.75</PRECIO>
</ITEM>
<cd:ITEM>
<cd:TITULO>
Violin Concertos Numbers 1, 2, and 3
</cd:TITULO>
<cd:COMPOSITOR>Mozart</cd:COMPOSITOR>
<cd:PRECIO>$16.49</cd:PRECIO>
</cd:ITEM>
<ITEM Estado="out">
<TITULO>The Legend of Sleepy Hollow</TITULO>
<AUTOR>Washington Irving</AUTOR>
<PRECIO>$2.95</PRECIO>
</ITEM>
<ITEM Estado="in">

XML - Página 12
Default.xml
<TITULO>The Marble Faun</TITULO>
<AUTOR>Nathaniel Hawthorne</AUTOR>
<PRECIO>$10.95</PRECIO>
</ITEM>
</COLECCION>

Ámbito de los namespaces


Los elementos no cualificados (esto es, sin prefijo relativo a un namespace) se consideran
pertenecientes al namespace por defecto más interno. En el siguiente ejemplo, LIBRO,
TITULO y AUTOR corresponden al espacio de nombres por defecto (el de LIBRO), mientras
que EDITORIAL y NOMBRE pertenecen al espacio de nombres más interno:

Ámbito de los namespaces

<LIBRO xmlns="www.bookstuff.org/bookinfo">
<TITULO>All About XML</TITULO>
<AUTOR>Joe Developer</AUTOR>
<EDITORIAL xmlns="urn:publishers:publinfo">
<NOMBRE>Microsoft Press</NOMBRE>
</EDITORIAL>
</LIBRO>

Namespaces y atributos
A diferencia de los elementos (que, salvo que se indique lo contrario, pertenecen al espacio de
nombres por defecto), los atributos NO pertenecen a ningún espacio de nombres, incluso
aunque exista un espacio de nombres por defecto.

XML - Página 13
Tecnologías relacionadas

XML en sí es bastante simple. Sin embargo, existen múltiples tecnologías relacionadas cuyo
aprendizaje requiere algo más de esfuerzo:

XML - Página 14
Esquemas XML
© Fernando Berzal Galiano & Francisco Cortijo Bon

¿Para qué sirven los esquemas XML?


Nociones sobre DTDs.
Elementos
Atributos

Sintaxis de XML Schema

Elementos

Atributos

Facetas

Estructuras de datos

Información adicional

Esquemas XML - Página 1


¿Para qué sirven los esquemas XML?

XML es un formato abierto muy útil para enviar información de un sitio a otro. En ocasiones,
sin embargo, la flexibilidad de XML puede resultar contraproducente. ¿Cómo sabemos que
los datos contenidos en un documento XML son consistentes con los que esperábamos
recibir? Los esquemas XML nos permiten verificarlo. Los esquemas XML permiten
especificar el formato correcto de un documento XML de modo que podamos identificar
documentos bien formados (validar el documento XML).

Los esquemas XML tienen, pues, dos cometidos fundamentales:


- publicar cómo se han de construir documentos XML correctos (de forma similar a
como se publica la interfaz de un componente software) y,

- permitir la validación de un documento conforme a un esquema particular (para,


por ejemplo, comprobar que los datos que nos llegan están en el formato
correcto).

Desde su creación, se han propuesto distintos estándares para la especificación de esquemas


XML, siendo DTD y XSD los más utilizados. En la actualidad, DTD (Document Type
Definition) está cayendo en desuso, ya que los esquemas XSD (XML Schema Definition) se
definen utilizando documentos XML, mientras que DTD utiliza un formato que no es XML.

Los esquemas XML y las definiciones DTD suelen especificarse en ficheros independientes,
lo que facilita la tarea de mantenimiento ya que un solo fichero (de esquema o DTD) puede
servir de referencia a muchos ficheros de datos XML.

Nociones sobre DTDs.


Para utilizar una DTD como mecanismo de restricción, se especifica lo siguiente en el
documento XML:

<?xml version="1.0"?>
<!DOCTYPE Libro SYSTEM "libro.dtd">
.....

SYSTEM sirve para DTDs "personales". Se puede espicificar un fichero local o un fichero
accesible a través de una URL. Se puede especificar una DTD pública con PUBLIC, en la que
queda reflejado el propietario de la misma, una descripción y el idioma.

Esquemas XML - Página 2


<!DOCTYPE elem_raiz PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

DTD para un ejemplo que contenga elementos de tipo libro:

<?xml version="1.0"?>
<!ELEMENT Libro
(Titulo, Catalogo:Seccion, Catalogo:SubSeccion,
Contenido, Compra, Copyright)>
<!ATTLIST Libro
xmlns CDATA #REQUIRED
xmlns:Catalogo CDATA #REQUIRED
>
<!ELEMENT Titulo (#PCDATA)>
<!ELEMENT Catalogo:Seccion (#PCDATA)>
<!ELEMENT Catalogo:SubSeccion (#PCDATA)>
<!ELEMENT Contenido ((Capitulo+)|(Capitulo+, Separacion?)+)>
<!ELEMENT Capitulo (Tema, Seccion+)>
<!ATTLIST Capitulo
materia (XML|Java) "Java"
>
<!ELEMENT Tema (#PCDATA)>
<!ELEMENT Seccion (#PCDATA)>
<!ATTLIST Seccion
apartados CDATA #REQUIRED
dificil (si|no) "no"
>
<!ELEMENT Separacion EMPTY>
<!ELEMENT Compra (#PCDATA)>
<!ELEMENT Copyright (#PCDATA)>

Elementos
Los elementos permitidos se especifican con ELEMENT, seguido del nombre y el tipo del
elemento. Los elementos que se pueden anidar dentro de otros se especifican entre paréntesis
y separados por comas. Importa el orden. El tipo menos restrictivo es ANY, que permite
cualquier contenido para un elemento. Para datos de tipo texto, se usa #PCDATA. Para
elementos vacíos, EMPTY.

Modificadores de número de ocurrencias:


- ?: Una vez o ninguna

- +: Al menos una vez

- *: Cualquier número de veces o ninguna

Esquemas XML - Página 3


- (nada): Exactamente una vez

- Para opciones alternativas: separar con |.

Atributos
Los atributos permitidos para un elemento se especifican con ATTLIST y el nombre del
elemento seguido de los nombres de los atributos, con un tipo y modificador obligatorios. El
tipo del atributo puede ser CDATA para cualquier valor, o una enumeración de los valores
permitidos.

Otros posibles tipos son: NMTOKEN para restringir el valor a un nombre XML válido (es
decir, que empiece con una letra o guión de subrayado y contenga sólo letras, números,
guiones de subrayado, guiones y puntos, sin espacios) ID, además de las restricciones que
impone NMTOKEN, impone que el valor sea único en todo el documento. El modificador
puede ser #REQUIRED para atributos obligatorios, #IMPLIED para opcionales, o #FIXED
valor_fijo para valores fijos. También puede ser un valor por defecto.

Esquemas XML - Página 4


Sintaxis de XML Schema

El siguiente ejemplo muestra un sencillo esquema XML que podría ser útil para gestionar los
productos existentes en un almacén:

<?xml version="1.0" encoding="utf-8"?>


<xsd:schema id="stock"
xmlns:xsd="http://www.w3c.org/2001/XMLSchema"
targetNamespace="http://elvex.ugr.es/stock.xsd">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="ID" type="xsd:unsignedInt" />
<xsd:element name="description" type="xsd:string" />
<xsd:element name="price" type="xsd:decimal" />
<xsd:element name="quantity" type="xsd:integer" />
</xsd:sequence>
</xsd:complexType>
</xsd:schema>
La etiqueta xsd:schema del documento XML anterior está definida en el estándar XSD y
es la que nos permite definir esquemas de acuerdo con el estándar del W3C. El atributo
targetNamespace nos permite asociar el esquema al espacio de nombres indicado (para
diferenciarlo de otros esquemas stock).

A continuación, la etiqueta xsd:complexType nos permite definir tipos de forma similar a


como se especifican los tipos definidos por el usuario en un lenguaje de programación,
indicando los elementos correspondientes a cada dato almacenado acerca de los productos de
nuestro almacén, su identificador y su tipo.

Esquemas XML - Página 5


Elementos

Un elemento (etiqueta xsd:element) se utiliza para describir datos.

Los elementos se utilizan para especificar las etiquetas válidas en un documento XML
(name) y su tipo (type), tal como aparece en el ejemplo anterior del almacén. Además, el
orden en que aparecen los elementos en el esquema XML determina el orden en que han de
aparecen dentro de un documento XML que se ajuste al esquema.

La siguiente tabla muestra algunos de los tipos permitidos y su equivalencia con los tipos de
la plataforma .NET:

Tipo XSD Tipo .NET


anyType object
Boolean bool
Byte sbyte
date | dateTime | time DateTime
decimal decimal
double double
duration Timespan
float single
ID | Name string
int Int32
integer | long Int64
short Int16
string string
unsignedByte Byte
unsignedInt UInt32
unsignedLong UInt64
unsignedShort UInt16
Además de poder indicar su nombre y su tipo, podemos especificar restricciones adicionales
para los elementos de un documento XML.minOccurs y maxOccurs nos permiten
especificar el número mínimo y el número máximo de veces que un elemento puede aparecer
en el documento (por defecto, 1).

Esquemas XML - Página 6


Atributos

Los atributos son similares a los elementos, si bien un atributo ha de ser de un tipo simple y
tiene declararse justo antes de cerrar la etiqueta xsd:complexType. A diferencia de los
elementos, los atributos pueden aparecer en cualquier orden y no pueden incluir otros
elementos (al ser de tipos simples). No obstante, su característica más interesante es que
pueden ser opcionales y se les puede asignar un valor por defecto:

<xsd:attribute name="rebate" type="xsd:decimal" />


El atributo use de xsd:attribute puede utilizarse para especificar si la presencia del
atributo es esencial ("required"), opcional ("optional") o incluso si está prohibida
("prohibited"), aunque esta última opción no resulta especialmente útil.

Esquemas XML - Página 7


Facetas

Las facetas forman parte de la definición de elementos y atributos de un esquema XML y nos
permiten especificar restricciones adicionales sobre los datos que pueden aparecer en un
documento XML válido:

Por ejemplo, podemos definir un tipo de dato que sólo permita almacenar valores enteros
entre 0 y 10:

Rango de valores

<xsd:simpleType name="nota">
<xsd:restriction base="decimal">
<xsd:minInclusive value="0" fixed="true" />
<xsd:maxInclusive value="10" fixed="true" />
</xsd:restriction>
</xsd:simpleType>
El tipo nota que hemos definido está basado en el tipo intrínseco decimal y, en su
definición, se especifican dos facetas (su valor mínimo y su valor máximo). El uso de fixed
evita que alguien pueda modificar las facetas especificadas en la definición del tipo (por
ejemplo, al declarar un nuevo tipo basado en nota).

También podemos especificar el conjunto de valores permitidos para un tipo de dato:

Tipo enumerado

<xsd:simpleType name="sexo">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="hombre"/>
<xsd:enumeration value="mujer"/>
<xsd:enumeration value="???"/>
</xsd:restriction>
</xsd:simpleType>
O incluso especificar un patrón al que han de atenerse los valores válidos de un tipo
(utilizando expresiones regulares):

SKU (Stock Keeping Unit): Código para identificar productos (p.ej. 976-FB)

<xsd:simpleType name="SKU">
<xsd:restriction base="xsd:string">
<xsd:pattern value="\d{3}-[A-Z]{2}"/>
</xsd:restriction>
</xsd:simpleType>

Esquemas XML - Página 8


SKU (Stock Keeping Unit): Código para identificar productos (p.ej. 976-FB)

Además de poder especificar tipos enumerados y expresiones regulares, las facetas incluidas
en el estándar XSD permiten especificar la longitud de una cadena o de una lista (length,
minLength y maxLength), si se permite la presencia de espacios en blanco (whiteSpace),
el intervalo de valores permitido (minInclusive, minExclusive, maxInclusive,
maxExclusive) y el número de dígitos de un valor decimal (totalDigits y
fractionDigits).

Esquemas XML - Página 9


Estructuras de datos

Los tipos complejos como el utilizado en el ejemplo del almacén son similares a los tipos
enumerados y, en concreto, suelen utilizarse para representar tablas. Si le asignamos un
nombre al tipo especificado, lo que estamos haciendo es definir un tipo abstracto que se podrá
utilizar en la definición de otros elementos, como en:

<xsd:schema
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:element name="purchaseOrder"
type="PurchaseOrderType"/>
<xsd:element name="comment" type="xsd:string"/>
<xsd:complexType name="PurchaseOrderType">
<xsd:sequence>
<xsd:element name="shipTo" type="Address"/>
<xsd:element name="billTo" type="Address"/>
<xsd:element ref="comment" minOccurs="0"/>
<xsd:element name="items" type="Items"/>
</xsd:sequence>
<xsd:attribute name="orderDate" type="xsd:date"/>
</xsd:complexType>
<xsd:complexType name="Address">
<xsd:sequence>
<xsd:element name="name" type="xsd:string"/>
<xsd:element name="street" type="xsd:string"/>
<xsd:element name="city" type="xsd:string"/>
<xsd:element name="zip" type="xsd:decimal"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="Items">
<xsd:sequence>
<xsd:element name="item"
minOccurs="0" maxOccurs="unbounded">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="product" type="xsd:string"/>
<xsd:element name="quantity" type="xsd:integer" />
<xsd:element name="price" type="xsd:decimal"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
</xsd:schema>
Cuando nos interesa permitir que en dentro de un elemento aparezcan elementos alternativos

Esquemas XML - Página 10


en vez de una secuencia de ellos, podemos utilizar un bloque choice:

<xsd:complexType name="PurchaseOrderType">
<xsd:sequence>
<xsd:choice>
<xsd:group ref="shipAndBill"/>
<xsd:element name="singleAddress" type="Address"/>
</xsd:choice>
<xsd:element ref="comment" minOccurs="0"/>
<xsd:element name="items" type="Items"/>
</xsd:sequence>
<xsd:attribute name="orderDate" type="xsd:date"/>
</xsd:complexType>
<xsd:group name="shipAndBill">
<xsd:sequence>
<xsd:element name="shipTo" type="Address"/>
<xsd:element name="billTo" type="Address"/>
</xsd:sequence>
</xsd:group>
Aparte de definir tipos estructurados, XSD nos permite definir listas como si fuesen tipos de
datos simples. Por ejemplo, en el documento XML:

<lista>20003 15037 95977 95945</lista>


y en el esquema XSD:+

<xsd:simpleType name="lista">
<xsd:list itemType="xsd:integer"/>
</xsd:simpleType>
Además, los esquemas XML nos permiten definir claves, tanto primarias como externas:

<xsd:schema targetNamespace="http://elvex.ugr.es/informe"
xmlns="http://elvex.ugr.es/informe"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
attributeFormDefault="unqualified"
elementFormDefault="qualified">
<xsd:annotation>
<xsd:documentation xml:lang="es">
Informe de proveedores y piezas
</xsd:documentation>
</xsd:annotation>
<xsd:element name="informe">
<xsd:complexType>
<xsd:sequence>

Esquemas XML - Página 11


<xsd:element name="proveedores"
type="Proveedores">
<xsd:keyref name="refPieza" refer="keyPieza">
<xsd:selector xpath="proveedor/pieza" />
<xsd:field xpath="@sku" />
</xsd:keyref>
</xsd:element>
<xsd:element name="piezas" type="Piezas" />
</xsd:sequence>
<xsd:attribute name="fecha" type="xsd:date" />
</xsd:complexType>
<xsd:unique name="uniqProveedor">
<xsd:selector xpath="proveedores/proveedor" />
<xsd:field xpath="@id" />
</xsd:unique>
<xsd:key name="keyPieza">
<xsd:selector xpath="piezas/pieza" />
<xsd:field xpath="@sku" />
</xsd:key>
</xsd:element>
<xsd:complexType name="Proveedores">
<xsd:sequence>
<xsd:element name="proveedor"
maxOccurs="unbounded">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="suministro"
maxOccurs="unbounded">
<xsd:complexType>
<xsd:complexContent>
<xsd:restriction
base="xsd:anyType">
<xsd:attribute name="sku"
type="SKU" />
<xsd:attribute name="cantidad"
type="xsd:positiveInteger" />
</xsd:restriction>
</xsd:complexContent>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
<xsd:attribute name="id"
type="xsd:positiveInteger" />
</xsd:complexType>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="Piezas">
<xsd:sequence>
<xsd:element name="pieza" maxOccurs="unbounded">
<xsd:complexType>
<xsd:simpleContent>
<xsd:extension base="xsd:string">
<xsd:attribute name="sku" type="SKU" />

Esquemas XML - Página 12


</xsd:extension>
</xsd:simpleContent>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
<xsd:simpleType name="SKU">
<xsd:restriction base="xsd:string">
<xsd:pattern value="\d{3}-[A-Z]{2}" />
</xsd:restriction>
</xsd:simpleType>
</xsd:schema>

Dado el esquema anterior, el siguiente documento XML sería válido:

<informe xmlns="http://elvex.ugr.es/informe"
fecha="2002-12-31">
<proveedores>
<proveedor id="95819">
<suministro sku="872-AA" cantidad="1" />
<suministro sku="926-AA" cantidad="1" />
<suministro sku="833-AA" cantidad="1" />
<suministro sku="455-BX" cantidad="1" />
</proveedor>
<proveedor id="63143">
<suministro sku="455-BX" cantidad="4" />
</proveedor>
</proveedores>
<piezas>
<pieza sku="872-AA">Monitor</pieza>
<pieza sku="926-AA">Impresora</pieza>
<pieza sku="833-AA">Escáner</pieza>
<pieza sku="455-BX">CD-R</pieza>
</piezas>
</informe>

Esquemas XML - Página 13


Información adicional

http://www.w3c.org/TR/xmlschema-0/

Esquemas XML - Página 14


XML en Visual Studio .NET
© Francisco Cortijo Bon

Herramientas de diseño para XML


Crear un esquema XML con el diseñador XML

Crear ficheros de datos XML, asociar esquemas y validar


datos.

Un ejercicio: diseñar un esquema XML

XML en Visual Studio .NET - Página 1


Herramientas de diseño para XML

Visual Studio incluye una herramienta (el diseñador XML) que nos permite hacer casi de todo
con documentos XML y esquemas XSD de una forma similar a como se trabaja con bases de
datos en Access.

Crear un esquema XML con el diseñador XML


Vamos a ilustrar cómo crear un esquema XML para un problema en el que se gestionan
pedidos.

1. Crear proyecto y agregar esquema XML.


- Crear un proyecto de Aplicación para Windows.

En el menú Archivo, elija Nuevo y, a continuación, haga clic en Proyecto para mostrar
el cuadro de diálogo Nuevo proyecto. Seleccione Proyectos de Visual C# en el
panel Plantillas y, a continuación, seleccione Aplicación para Windows. Asigne
al proyecto el nombre EjemploEsquema.
- Agregar un esquema XML al proyecto.

En el menú Proyecto, seleccione Agregar nuevo elemento (o situados en el


explorador de soluciones, pinchar con el botón derecho sobre EjemploEsquema y
seleccionar Agregar y Agregar nuevo elemento) y, a continuación, haga doble clic
en el icono Esquema XML en el cuadro de diálogo Agregar nuevo elemento.
Cambiar el nombre por EsquemaPedido. Aparecerá el Diseñador XML.

2. Definir los tipos de datos.

Antes de crear la tabla relacional, primero creará definiciones de tipos simple y complejo que
utilizará para dar formato a elementos específicos del esquema de pedido. Los nuevos tipos se
crean utilizando tipos de datos XML existentes, como string e integer.

En primer lugar definirá un tipo simple, que se denominará CodigoProvincia. Este tipo
simple se utilizará para limitar el tamaño de una cadena a dos caracteres.
- Agregar un objeto simpleType al proyecto.

- Si aún no está abierto, haga doble clic en el archivo EsquemaPedido.xsd para


abrir el Diseñador XML.

XML en Visual Studio .NET - Página 2


- Haga clic en la ficha Esquema XML del Cuadro de herramientas y
arrastre un objeto simpleType hasta la superficie del diseñador.

- Cambie el nombre del objeto simpleType haciendo clic en el primer cuadro de


texto del encabezado y reemplazando simpleType1 por CodigoProvincia.

- Establezca el tipo base del tipo CodigoProvincia haciendo clic en la lista


desplegable del encabezado y seleccionando string.

- Colóquese en la primera columna de la fila siguiente y seleccione facet en la


lista desplegable.

- Colóquese en la siguiente celda, seleccione lenght en la lista desplegable y


establezca el valor 2 en la siguiente columna.
De esta manera se exige que el valor escrito en el campo CodigoProvincia
tenga dos caracteres.

CodigoProvincia debe tener este aspecto en la vista de esquema:

XML en Visual Studio .NET - Página 3


- Haga clic en la ficha XML en la parte inferior izquierda del Diseñador XML, para
ver el código XML que se ha agregado:

<xs:simpleType name="CodigoProvincia">
<xs:restriction base="xs:string">
<xs:length value="2" />
</xs:restriction>
</xs:simpleType>

Este tipo simple CodigoProvincia se utilizará para definir el elemento


Provincia del tipo complejo que creará en la siguiente sección.

- Agregar objetos complexType al proyecto.

El tipo complejo TipoDireccion define un conjunto de elementos que aparecerán en


cualquier elemento con tipo TipoDireccion. Por ejemplo, un elemento del tipo
FacturarA incluirá información de nombres y dirección cuando se establece que un
componente suyop sea de tipo TipoDireccion. Mediante la creación del tipo complejo y
utilizándolo en un elemento, se genera una relación anidada.
- Haga clic en la ficha Esquema del Diseñador XML.

- Haga clic en la ficha Esquema XML del Cuadro de herramientas y


arrastre un objeto complexType hasta la superficie del diseñador.

- Cambie el nombre del tipo por TipoDireccion.

- Añada un elemento al tipo complejo haciendo clic en la primera celda de la


primera fila y seleccionando element en la lista desplegable. En la segunda
columna, cambie element1 por Nombre. En la tercera columna, acepte el valor
predeterminado string.

- Añada nuevos elementos al tipo complejo de manera que tenga un aspecto similar
al siguiente en la vista de esquema:

XML en Visual Studio .NET - Página 4


- Para ver el código XML que se ha agregado al archivo .xsd, haga clic en la ficha
XML en la parte inferior del diseñador. Verá el siguiente código XML:

<xs:complexType name="TipoDireccion">
<xs:sequence>
<xs:element name="Nombre" type="xs:string" />
<xs:element name="Calle" type="xs:string" />
<xs:element name="Ciudad" type="xs:string" />
<xs:element name="Provincia"
type="CodigoProvincia" />
<xs:element name="CodPostal" type="xs:integer"/>
</xs:sequence>
</xs:complexType>

3. Crear una tabla relacional.

Cuando se arrastra el objeto element del Cuadro de herramientas a la superficie de


diseño, realmente se agrega un elemento que contiene un complexType sin nombre. Al
incluir el tipo complejo sin nombre se define el elemento para que sea una tabla relacional.

A continuación, es posible agregar elementos adicionales bajo complexType para definir


los campos (o columnas) de la relación. Si define uno de estos nuevos elementos como un
nuevo complexType sin nombre, está creando una relación anidada dentro de la relación
primaria con sus propias columnas únicas.

Se trata de crear una taba relacional llamada Pedidos, agregar un elemento Items a esa
tabla, especificando que Items sea, a su vez, de tipo complexType sin nombre, lo que
permite la repetición de objetos Item para un sólo registro de pedido.

Como se está definiendo una nueva tabla relacional hace que aparezca un nuevo elemento en
la superficie de diseño. En la relación de nuevos Items , al agregar el elemento Item y
establecer su tipo en complexType sin nombre, se crea otra tabla relacional, que también
aparece en el superficie de diseño.
- Agregar un elemento al proyecto.

XML en Visual Studio .NET - Página 5


- Haga clic en el Cuadro de herramientas y, en la ficha Esquema XML,
arrastre un objeto element hasta la superficie de diseño.

- Cambie element1 a Pedidos para asignar un nombre al elemento. Puede dejar


el tipo de datos como queda por defecto: (Pedidos).

- Agregue un elemento a Pedidos haciendo clic en la primera celda de la primera


fila y seleccionando element en la lista desplegable. Dele al elemento el nombre
EnviarA y establezca que su tipo es TipoDireccion. El tipo Pedidos
tendrá este aspecto en la vista de esquema:

- Añada otro elemento llamado FacturarA y establezca que su tipo es


TipoDireccion. El tipo Pedidos tendrá ahora este aspecto en la vista de
esquema:

XML en Visual Studio .NET - Página 6


y se habrá añadido el siguiente código XML:

<xs:element name="Pedidos">
<xs:complexType>
<xs:sequence>
<xs:element name="EnviarA"
type="TipoDireccion" />
<xs:element name="FacturarA"
type="TipoDireccion" />
</xs:sequence>
</xs:complexType>
</xs:element>

- Crear otra tabla relacional anidada.

- Añadir un nuevo elemento a Pedidos. Llámele Items y establezca que su tipo


es Unnammed complexType.

XML en Visual Studio .NET - Página 7


- En el elemento Items, agregue un elemento, déle el nombre Item y establezca
que su tipo es Unnammed complexType. Cuando escriba el elemento Item
como anónimo, se agrega un elemento adicional a la superficie de diseño, que es
otra tabla relacional:

XML en Visual Studio .NET - Página 8


- Añada los siguientes elementos al objeto Item: Cantidad (tipo integer),
Precio (tipo decimal) e IDProducto (tipo integer).

Finamente, como el elemento Item puede repetirse indefinidamente para un


elemento Items seleccionar en el diseñador de esquemas el elemento Item
pinchando sobre su nombre y en la ventana de Propiedades establecer que
minOccurs sea 1 y que maxOccurs sea unbounded.

El código XML (completo) asociado a este esquema será, finamente:

<?xml version="1.0" encoding="utf-8" ?>


<xs:schema id="EsquemaPedido"
targetNamespace="http://tempuri.org/EsquemaPedido.xsd"
elementFormDefault="qualified"
xmlns="http://tempuri.org/EsquemaPedido.xsd"
xmlns:mstns="http://tempuri.org/EsquemaPedido.xsd"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:simpleType name="CodigoProvincia">
<xs:restriction base="xs:string">
<xs:length value="2" />

XML en Visual Studio .NET - Página 9


</xs:restriction>
</xs:simpleType>
<xs:complexType name="TipoDireccion">
<xs:sequence>
<xs:element name="Nombre" type="xs:string" />
<xs:element name="Calle" type="xs:string" />
<xs:element name="Ciudad" type="xs:string" />
<xs:element name="Provincia"
type="CodigoProvincia" />
<xs:element name="CodPostal"
type="xs:integer" />
</xs:sequence>
</xs:complexType>
<xs:element name="Pedidos">
<xs:complexType>
<xs:sequence>
<xs:element name="EnviarA"
type="TipoDireccion" />
<xs:element name="FacturarA"
type="TipoDireccion" />
<xs:element name="Items">
<xs:complexType>
<xs:sequence>
<xs:element name="Item" minOccurs="1"
maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="Cantidad"
type="xs:integer" />
<xs:element name="Precio"
type="xs:decimal" />
<xs:element name="IDProducto"
type="xs:integer" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>

Crear ficheros de datos XML, asociar esquemas y


validar datos.
Los ficheros XML son ficheros de texto y como tales pueden crearse con cualquier editor que
guarde los documentos en formato texto. Nosotros usaremos, por comodidad, Visual Studio
.NET para crear un fichero de datos XML.

En el menú Proyecto, seleccione Agregar nuevo elemento (o situados en el

XML en Visual Studio .NET - Página 10


explorador de soluciones, pinchar con el botón derecho sobre EjemploEsquema y
seleccionar Agregar y Agregar nuevo elemento) y, a continuación, haga doble clic
en el icono Archivo XML en el cuadro de diálogo Agregar nuevo elemento.
Cambiar el nombre por PedidosSeptiembre. Aparecerá una ventana de edición
conteniendo únicamente:

<?xml version="1.0" encoding="utf-8" ?>

listo para empezar a trabajar con él.

En primer lugar asociaremos a este fichero XML el esquema que creamos anteriormente. En
la ventana de Propiedades, seleccionar DOCUMENT, y en la propiedad targetSchema
seleccionar el esquema de la lista desplegable:

que hace que el fichero XML tenga el siguiente contenido:

<?xml version="1.0" encoding="utf-8" ?>


<Pedidos xmlns="http://tempuri.org/EsquemaPedido.xsd">

XML en Visual Studio .NET - Página 11


</Pedidos>

Observar que automáticamente se ha escrito la etiqueta correspondiente al elemento raiz


Pedidos. Visual Studio .NET ayuda a la introducción de datos, ya que al escribir el ángulo
de apertura (<) nos indica qué elementos podemos utilizar:

Esta ayuda es contextual, por lo que si estamos completando el elemento EnviarA, la ayuda
ofrecida será:

Completar hasta escribir lo siguiente:

<?xml version="1.0" encoding="utf-8" ?>


<Pedidos xmlns="http://tempuri.org/EsquemaPedido.xsd">
<EnviarA>
<Calle>C/ Recogidas, 23</Calle>

XML en Visual Studio .NET - Página 12


<Ciudad>Granada</Ciudad>
<CodPostal>18003</CodPostal>
<Nombre>Joaquín Núñez Argüelles</Nombre>
<Provincia>Granada</Provincia>
</EnviarA>
<FacturarA>
<Calle>C/ Motril, 44</Calle>
<Ciudad>Albolote</Ciudad>
<CodPostal>18220</CodPostal>
<Nombre>VISTUDNET S.A.</Nombre>
<Provincia>Granada</Provincia>
</FacturarA>
<Items>
<Item>
<Cantidad>1</Cantidad>
<IDProducto>11111</IDProducto>
<Precio>200.45</Precio>
</Item>
<Item>
<Cantidad>3</Cantidad>
<IDProducto>11122</IDProducto>
<Precio>100.22</Precio>
</Item>
</Items>
</Pedidos>

Si cambiamos el modo de vista a Datos encontramos una interfaz cómoda que permite
añadir, modificar, borrar, etc:

Finalmente, si queremos validar los datos XML (PedidosSeptiembre.xml) respecto al


esquema (EsquemaPedido.xsd) seleccionaremos XML en el menú principal y Validar
datos XML. Si todo es correcto en la barra de estado se indica que No se encontraron
errores de validación.

XML en Visual Studio .NET - Página 13


Un ejercicio: diseñar un esquema XML

Se trata de realizar un esquema XML y de crear un fichero de datos para guardar los datos de
nuestra biblioteca personal. La biblioteca consta de una serie (indeterminada en número) de
libros. Cada libro se identifica por: título, autor, número de páginas, precio y tipo de
encuadernación. Para hacer más fácil su clasificación se quieren registrar los géneros
(literarios) en los que puede encuadrarse el libro, teniendo en cuenta que un libro puede tener
asociado un número máximo de cinco géneros. Finalmente, queremos tener en cuenta si el
libro está disponible o no (se supone entonces que lo hemos prestado).

Antes de empezar con el esquema debemos tener en cuenta algunas consideraciones que nos
facilitarán la tarea de diseño:
- El precio de un libro debe ser de tipo real (con decimales...) y el valor mínimo
debe ser 0.

- Queremos que la etiqueta de cada género tenga una longitud mínima de 1 carácter.

- El número de páginas debe ser un valor entero y positivo.

1. Crear proyecto y agregar esquema XML.

Crear un proyecto de Visual C# llamado Bibioteca y agregar un esquema XML llamado


EsquemaBiblioteca.

2. Definir los tipos de datos.

Se trata de definir en primer lugar los tipos simples y a continuación los tipos complejos que
hagan uso de los tipos simples ya definidos. Dejaremos los géneros para el final.
- Arrastre un objeto simpleType hasta la superficie del diseñador y cambie el
nombre del tipo por TipoPrecio, establezca el tipo base a float y restrinja su
valor mínimo a 0.0: colóquese en la primera columna de la fila siguiente,
seleccione facet en la lista desplegable, colóquese en la siguiente celda,
seleccione minInclusive en la lista desplegable y establezca el valor 0.0 en
la siguiente columna.

- Agregar un tipo complejo para representar a cada libro. El tipo complejo

XML en Visual Studio .NET - Página 14


TipoLibro define el conjunto de elementos que aparecerá en cualquier
elemento con tipo TipoLibro. Arrastre un objeto complexType hasta la
superficie del diseñador y cambie el nombre del tipo por TipoLibro, añada los
elementos al tipo complejo siguiendo las indicaciones de la figura:

3. Crear una tabla relacional.

La biblioteca consta de una serie o secuencia indefinida de elementos de tipo TipoLibro.


Se trata de añadir un elemento al esquema arrastrando un objeto de tipo element a la
superficie de dieño

Cambie element1 a Biblioteca para asignar un nombre al elemento. Puede dejar el tipo
de datos como queda por defecto: (Biblioteca).

En el elemento Biblioteca, agregue un elemento, déle el nombre Libro y establezca que


su tipo es TipoLibro:

XML en Visual Studio .NET - Página 15


Como el elemento Libro puede repetirse indefinidamente para un elemento Biblioteca
seleccionar en el diseñador de esquemas el elemento Libro pinchando sobre su nombre y en
la ventana de Propiedades establecer que minOccurs sea 1 y que maxOccurs sea
unbounded.

4. Gestión de los géneros.

Recordemos que cada libro tiene, al menos, un género asociado y que queremos restringir el
número máximo de géneros a 5. La idea es que si un libro tiene, por ejemplo, dos géneros, su
código XMl será así:

...
<Biblioteca>
<Libro>
<Autor>Arturo Pérez Reverte</Autor>
<Titulo>El capitán Alatriste</Titulo>
...
<Generos>
<Genero>Novela</Genero>
<Genero>Historica</Genero>
</Generos>
</Libro>
...
</Biblioteca>

- Cree el tipo simple TipoGenero que está basado en el tipo string


restringiendo la longitud mínima a 1.

XML en Visual Studio .NET - Página 16


- Añada al tipo complejo TipoLibro un nuevo elemento lamado Generos de
tipo Unnamed conplexType. Observar que al añadir el elemento Generos
como anónimo, se agrega un elemento adicional a la superficie de diseño, que es
otra tabla relacional:

- Añada un elemento al objeto Generos llamdo Genero de tipo TipoGenero.


Finamente, como el elemento Genero puede repetirse entre 1 y 5 veces
seleccionar en el diseñador de esquemas el elemento Genero pinchando sobre su
nombre y en la ventana de Propiedades establecer que minOccurs es 1 y
que maxOccurs es 5:

XML en Visual Studio .NET - Página 17


El código XML (completo) asociado a este esquema (EsquemaBiblioteca.xsd) será,
finamente:

<?xml version="1.0" encoding="utf-8" ?>


<xs:schema id="EsquemaBiblioteca"
targetNamespace="http://tempuri.org/EsquemaBiblioteca.xsd"
elementFormDefault="qualified"

XML en Visual Studio .NET - Página 18


xmlns="http://tempuri.org/EsquemaBiblioteca.xsd"
xmlns:mstns="http://tempuri.org/EsquemaBiblioteca.xsd"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:simpleType name="TipoPrecio">
<xs:restriction base="xs:float">
<xs:minInclusive value="0.0" />
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="TipoGenero">
<xs:restriction base="xs:string">
<xs:minLength value="1" />
</xs:restriction>
</xs:simpleType>
<xs:complexType name="TipoLibro">
<xs:sequence>
<xs:element name="Titulo" type="xs:string" />
<xs:element name="Autor" type="xs:string" />
<xs:element name="NumPags"
type="xs:positiveInteger" />
<xs:element name="Precio" type="TipoPrecio"/>
<xs:element name="Generos">
<xs:complexType>
<xs:sequence>
<xs:element name="Genero"
type="TipoGenero"
maxOccurs="5" minOccurs="1" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="Disponible" type="xs:boolean" />
</xs:complexType>
<xs:element name="Biblioteca">
<xs:complexType>
<xs:sequence>
<xs:element name="Libro" type="TipoLibro"
minOccurs="1" maxOccurs="unbounded" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>

5. Creación de un fichero XMl coherente con el esquema.

Añadir al proyecto un fichero XML (menú Proyecto, Agregar nuevo elemento,


Archivo XML) llamado LibrosDeCasa.xml.

Asociar a este fichero XML el esquema EsquemaBiblioteca.xsd: En la ventana de


Propiedades, seleccionar DOCUMENT, y en la propiedad targetSchema seleccionar el
esquema de la lista desplegable.

Escribir el contenido del fichero y validar los datos contra el esquema. Utilizar estos datos

XML en Visual Studio .NET - Página 19


para el ejemplo, añadiendo más si lo considera oportuno.

<?xml version="1.0" encoding="utf-8" ?>


<Biblioteca
xmlns="http://tempuri.org/EsquemaBiblioteca.xsd">
<Libro Disponible="false">
<Titulo>El Rabino</Titulo>
<Autor>Noah Gordon</Autor>
<NumPags>650</NumPags>
<Precio>100.0</Precio>
<Generos>
<Genero>Religioso</Genero>
<Genero>Novela</Genero>
<Genero>Moderna</Genero>
</Generos>
</Libro>
<Libro Disponible="true">
<Titulo>El Médico</Titulo>
<Autor>Noah Gordon</Autor>
<NumPags>890</NumPags>
<Precio>200.0</Precio>
<Generos>
<Genero>Novela</Genero>
<Genero>Histórica</Genero>
</Generos>
</Libro>
<Libro Disponible="true">
<Titulo>La Sangre de Dios</Titulo>
<Autor>Nicholas Wilcox</Autor>
<NumPags>300</NumPags>
<Precio>300.0</Precio>
<Generos>
<Genero>Novela</Genero>
<Genero>Ciencia Ficción</Genero>
</Generos>
</Libro>
<Libro Disponible="true">
<Titulo>El Capitán Alatristre</Titulo>
<Autor>Arturo Pérez Reverte</Autor>
<NumPags>450</NumPags>
<Precio>100.0</Precio>
<Generos>
<Genero>Histórica</Genero>
<Genero>Novela</Genero>
</Generos>
</Libro>
</Biblioteca>

XML en Visual Studio .NET - Página 20


Presentación y transformación
de documentos XML
© Francisco Cortijo Bon

Hojas de estilo CSS


Hojas de estilo CSS en Visual Studio .NET

Transformaciones XSLT
Introducción

Ventajas y desventajas

Formas de uso

Crear documentos XSLT en Visual Studio .NET

Escribir transformaciones XSLT


Ejemplo 1
Ejemplo 2
Ejemplo 3
Ejemplo 4
Ejemplo 5

Presentación y transformación de documentos XML - Página 1


Hojas de estilo CSS

CSS es el acrónimo de Cascading Style Sheet (hoja de estilo en cascada).

CSS es un lenguaje de hojas de estilo que se utiliza normalmente para controlar la


presentación de documentos HTML, pero también se puede utilizar con documentos XML. Su
principal característica, en contraste con el lenguaje XSLT, es su sencillez.

Ventajas:
- Fácil de aprender y utilizar. Muchos desarrolladores ya lo conocen.

- No requiere la creación de una página HTML para visualizar código XML.

- Consume poca memoria y tiempo de proceso, pues no construye una


representación en árbol del documento.

- Muestra el documento según se va procesando.

Desventajas:
- Utiliza una sintaxis diferente a la del XML.

- Sólo sirve para visualizar documentos en un navegador.

- No es muy flexible:
- No permite realizar manipulaciones sobre el documento, tales como añadir y
borrar elementos, realizar ordenaciones, etc.

- Sólo permite acceder al contenido de los elementos, no a los atributos, no permite


instrucciones de proceso, etc.

Para usar una hoja de estilo CSS para presentar el contenido de un documento XML hay que
añadir la siguiente línea en el prólogo:

<?xml-stylesheet type="text/css" href="fichero.css" ?>


donde fichero.css es el nombre del fichero CSS que contiene las reglas de formato.

Un ejemplo sencillo

Un fichero de estilo sencillo MuySencillo.css asociado al fichero


LibrosDeCasa.xml podría ser:

Presentación y transformación de documentos XML - Página 2


/* Fichero: MuySencillo.css */
Titulo
{
display:block;
margin-top:12pt;
font-size:15pt
}
Autor
{
display:block;
color:Aqua;
font-style:italic
}
Precio
{
font-weight:bold
}
NumPags
{
font-size: 10pt;
left: 30pt;
color: maroon;
font-style: italic;
font-family: Arial;
position: static;
top: 10pt;
}
Generos
{
display: none;
}

Si se añade la línea oportuna en LibrosDeCasa.xml para usar el fichero de estilo


MuySencillo.css:

<?xml version="1.0" encoding="utf-8" ?>


<?xml-stylesheet type="text/css"
href="MuySencillo.css" ?>
<Biblioteca
xmlns="http://tempuri.org/EsquemaBiblioteca.xsd">
<Libro Disponible="false">
<Titulo>El Rabino</Titulo>
<Autor>Noah Gordon</Autor>
<NumPags>650</NumPags>
......

el resultado, visto en un navegador será:

Presentación y transformación de documentos XML - Página 3


Hojas de estilo CSS en Visual Studio .NET
Visual Studio .NET proporciona facilidades para asociar a un proyecto hojas de estilo CSS y
para construirlas empleando un asistente. Su uso es muy sencillo y pueden construirse hojas
de estilo complejas sin necesidad de conocer nada acerca de CSS.

En primer lugar veremos cómo crear una hoja de estilo con Visual Studio .NET.

Presentación y transformación de documentos XML - Página 4


En el menú Proyecto, seleccione Agregar nuevo elemento y, a continuación, haga
clic en el icono Hoja de estilos en el cuadro de diálogo Agregar nuevo
elemento. Cambiar el nombre por MiHojaCSS.css. Aparecerá el Diseñador de hojas
CSS:

Se trata de especificar el formato de cada elemento del documento XML especificando una
regla para cada elemento.

Como no hay ningún elemento llamado body lo borramos y escribimos, por ejemplo,
Titulo. Observar como se modifica el explorador de elementos en la parte izquierda del
diseñador CSS:

Presentación y transformación de documentos XML - Página 5


Ahora podremos especificar la transformación asociada al elemento Titulo. El formato
genérico es el que se muestra en el ejemplo:

Para establecer el formato de los elementos Titulo tenemos tres posibilidades:


- A) Pinchar con el botón derecho sobre Titulo en el explorador de elementos y
seleccionar Generar estilo.

- B) En la ventana Propiedades, en la propiedad Style pinchar en el botón de


elipsis.

- C) Escribir manualmente las transformaciones a aplicar. Requiere mucha


experiencia.

Presentación y transformación de documentos XML - Página 6


Se abrirá la ventana de diálogo Generador de estilos que nos permite definir
fácilmente el estilo del elemento seleccionado. El usuario selecciona categorías de formato
(fuente, color, etc) y especifica valores y Visual Studio .NET escribe en el fichero CSS el
código CSS correspondiente.

Dominar este asistente es cuestión de experimentar con él... Sin embargo debe saber dos cosas
importantes:
- Solo aparecen con formato los elementos que se han especificado y configurado.

- Aparecerán todos los elementos y aquellos que no hatan sido configurado se


mostrarán de cualquier manera.

- Si no quiere que aparezca un elemento debe especifcarlo en el formato. Por


ejemplo, si solo quisiera mostrar los autores de los libros se añadiría el elemento
Autor y se definiría el formato siguiente: Diseño, Mostrar y No mostrar

Completar la definición de formatos en MiHojaCSS.css para que quede así:

/* Fichero: MiHojaCSS.css */
Titulo
{
display: block;

Presentación y transformación de documentos XML - Página 7


font-weight: normal;
font-size: 15pt;
text-transform: capitalize;
color: red;
}
Generos
{
display: none;
}
Autor
{
display: none;
}
Precio
{
display: none;
}
NumPags
{
display: none;
}

y comprobar que el resultado es:

Presentación y transformación de documentos XML - Página 8


Transformaciones XSLT

Introducción
XSLT es el acrónimo de EXtensible Stylesheet Languaje Transformation.

XSL es un lenguaje que nos permite definir una representación o formato pra un documento
XML. Un mismo documento XML puede tener varias hoas de estilo XSL que lo muestren en
diferentes formatos (HTML, PDF, RTF, PostScript, etc.) Básicamente, XSL es un lenguaje
que define la transformación entre un documento XML de entrada y otro documento XML de
salida.

La aplicación de una hoja de estilo XSL a un documento XML puede ocurrir tanto en el
origen (por ejemplo, un servlet que convierta de XML a HTML para que sea mostrado en el
navegador de un ordenador conectado a un servidor web) o en el mismo navegador (por
ejemplo, Internet Explorer 6).

Para aclarar terminología, XSL es un estándar que consiste en:


- XSLT: Lenguaje para transformar documentos XML en otro formato (otro XML,
HTML, DHTML, texto plano, PDF, RTF, Word, etc.)

- XSL-FO (XSL Formatting Objects): Especificación que trata cómo deben ser los
objetos de formato para convertir XML a formatos binarios (PDF, Word,
imágenes, etc.). Todavía no ha alcanzado el estado de "recomendado por la
W3C".

- XPath: Lenguaje de consulta genérico para identificar (y seleccionar) elementos


de un documento XML.

La principal característica del lenguaje XSLT es su potencia. No es sólo un lenguaje para


visualizar documentos, sino en general para transformarlos y manipularlos. Esta
manipulación la gestiona un programa especial que se llama procesador XSLT.

Ventajas y desventajas
Ventajas:
- La salida no tiene por qué ser HTML para visualización en un navegador, sino
que puede estar en muchos formatos.

Presentación y transformación de documentos XML - Página 9


- Permite manipular de muy diversas maneras un documento XML: reordenar
elementos, filtrar, añadir, borrar, etc.

- Permite acceder a todo el documento XML, no sólo al contenido de los elementos.

- XSLT es un lenguaje XML, por lo que no hay que aprender nada especial acerca
de su sintaxis.

Desventajas:
- Su utilización es más compleja.

- Consume cierta memoria y capacidad de proceso, pues se construye un árbol con


el contenido del documento.

Formas de uso
- Visualizar directamente en un navegador el documento XML que tiene asociada
una hoja XSLT. El navegador debe tener incorporado un procesador XSLT.

- Ejecutar el procesador XSLT independientemente del navegador. Se le pasan las


entradas necesarias (fichero origen y hoja XSLT a utilizar) y genera la salida en
un fichero, con el que podemos hacer lo que queramos.

- Realizar las transformaciones dentro de un programa en el servidor y enviar a los


clientes sólo el resultado de la transformación.

Crear documentos XSLT en Visual Studio .NET


En el menú Proyecto, seleccione Agregar nuevo elemento y, a continuación, haga
clic en el icono Archivo XSLT en el cuadro de diálogo Agregar nuevo elemento.
Cambiar el nombre por XSLTSencillo.xslt.

Muy importante: Siempre se emplea el espacio de nombres


xmlns="http://www.w3.org/1999/XSL/Transform". Modificar el código XML
que escribe Visual Studio .NET en el fichero XSLTSencillo.xslt para que el prefijo del
espacio de nombres sea xsl:

<!-- Fichero: XSLTSencillo.XSLT -->


<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="1.0"

Presentación y transformación de documentos XML - Página 10


xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
</xsl:stylesheet>

Para usar un fichero XSLT desde un documento XML hay que añadir la siguiente línea en el
prólogo:

<?xml-stylesheet type="text/xsl" href="fichero.xslt" ?>


donde fichero.xslt es el nombre del fichero XSLT.

Por ejemplo, modificaremos el fichero LibrosDeCasa.xml para que quede como sigue:

<!-- Fichero: LibrosDeCasa.xml -->


<?xml version="1.0" encoding="utf-8" ?>
<?xml-stylesheet type="text/xsl" href="XSLTSencillo.xslt" ?>
<Biblioteca>
<Libro Disponible="false">
<Titulo>El Rabino</Titulo>
<Autor>Noah Gordon</Autor>
<NumPags>650</NumPags>
......

Solo falta escribir las transformaciones a aplicar en el fichero XSLT ...

Escribir transformaciones XSLT


- La idea es muy sencilla y todo está basado en considerar que los elementos que
forman el documento XML mantienen una relación jerárquica: son nodos del
árbol que determina la relación entre los elementos del documento XML.

- Una hoja de estilo XSL consta de una serie de reglas que determinan cómo va a
ocurrir la transformación. Cada regla se compone de:
- patrón (pattern).

- plantilla (template) o acción.

- Cada regla afecta a uno o varios elementos del documento XML.

- Sintácticamente, las reglas tienen tres partes:


- La marca de apertura que contiene un atributo match que describe a qué partes
del documento se aplica la regla (qué nodos están afectados). La sintaxis del

Presentación y transformación de documentos XML - Página 11


patrón (valor del atributo match) debe seguir las especificaciones del lenguaje
XPath.

- La parte central describe qué debe hacerse cuando se produce una coincidencia.

- La marca de cierre.

<xsl:template match="PATRON"> <!-- Apertura -->


<!-- Esta es la parte central -->
</xsl:template> <!-- Cierre -->

Así, cada elemento template se asocia con un fragmento del documento XML
(que puede ser un elemento o un conjunto de elementos) y se transforma en otro
fragmento de XML o HTML, de acuerdo a lo que se especifique en su interior.

RESUMEN: ¿Cómo se realiza la transformación?


- El documento origen se pasa al procesador XSLT.
- (El procesador carga una hoja de estilo XSLT)

- El procesador entonces:
- Carga los patrones especificadas en la hoja de estilo...

- Recorre el documento XML origen, nodo por nodo...

- Si un nodo se ajusta a un patrón:


- Aplica las acciones especificadas, y

- Proporciona el resultado en un nuevo documento en formato XML o HTML.

Otros elementos de XSL

Además de xsl:template, los elementos del espacio de nombres xsl (¿instrucciones


XSL?) que nos ayudan a escribir transformaciones son:
- xsl:apply-templates hace que se apliquen las reglas que siguen a todos los
nodos seleccionados.

<xsl:apply-templates />

Puede restringirse con el atributo select para especificar un subconjunto de

Presentación y transformación de documentos XML - Página 12


nodos.

<xsl:apply-templates select="PATRON">
.....
<xsl:apply-templates />

- xsl:value-of extrae un valor concreto (literal) del documento.

- xsl:for-each aplica una acción repetidamente para cada nodo de un conjunto.


En definitiva, se usa para iterar sobre una serie de elementos.

<xsl:for-each select="PLANTILLA">
.....
<xsl:for-each />

- xsl:if sirve para evaluar condiciones sobre valores de atributos o elementos.

<xsl:if test="EXPRESIÓN LÓGICA">


.....
<xsl:if />

- xsl:choose sirve para evaluar condiciones múltiples (tipo switch).

<xsl:choose>
<xsl:when test="EXPRESIÓN 1"> ... </xsl:when />
<xsl:when test="EXPRESIÓN 2"> ... </xsl:when />
.....
<xsl:otherwise> ... </xsl:otherwise />
<xsl:choose />

- xsl:sort ordena un conjunto de nodos de acuerdo a algún elemento. Por


ejemplo, para ordenar de forma creciente según el número de páginas:

<xsl:sort select="/Biblioteca/Libro/NumPags"
order="ascending" />

En este ejemplo hemos hecho uso de un patrón algo complejo que responde a una
expresión de XPath que puede interpretarse así: De la raiz del documento XML

Presentación y transformación de documentos XML - Página 13


(todo el documento) seleccionar los elementos Biblioteca y de éstos, los que
tengan como etiqueta Libro. Finalmente, de todos éstos seleccionaremos
únicamente los elementos NumPags.

XPath

Los patrones pueden ser muy complejos y, como hemos indicado, se especifican en un
lenguaje llamado XPath. Es un lenguaje de consulta usado para identificar y seleccionar
nodos (elementos) de un documento XML. Se caracteria por:
- Es declarativo (vs. procedimental).

- Es contextual ya que los resultados dependen del nodo "actual".

- Admite expresiones comunes: operadores de comparación, lógicos y matemáticos


(=, <, and, or, *, +, etc.)

Los operados empleados habitualmente para formar los patrones se describen en la siguiente
tabla:

Operador Descripción
/ Selección de hijo. Selecciona únicamente
a los descendientes directos. Al principio
del patrón el contexto es la raíz del
documento.
// Selección de descendientes. Selecciona
todos los descendientes.
. Selección del elemento actual (el
contexto).
* Todos (en el sentido habitual de este
operador)
@ Prefijo que se antepone al nombre de un
atributo.
[] Filtro sobre el conjunto de nodos
seleccionado.
Algunos ejemplos:

./AUTOR Selecciona todos los elementos AUTOR dentro del contexto actual (todos los hijos
del nodo actual que tengan como etiqueta AUTOR).

/LIBROS Selecciona los elementos (posiblemente uno solo) con etiqueta LIBROS que
cuelgan directamente de la raiz.

Presentación y transformación de documentos XML - Página 14


//AUTOR Selecciona todos los elementos AUTOR en cualquier parte del documento.

/LIBROS[@TEMA="XML"] Selecciona todos los elementos LIBROS de la raiz (los


seleccionados antes) y de éstos selecciona aquellos que tengan el valor XML en el atributo
TEMA.

Ejemplo 1
Se trata de mostrar una lista con todos los libros. Se incluye un encabezado y solo se muestra
el título de cada libro.

<!-- Fichero: XSLTSencillo.xslt -->


<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/Biblioteca">
<h2>LISTA DE LIBROS</h2>
<xsl:apply-templates />
<hr/>
</xsl:template>
<xsl:template match="Libro">
<p><xsl:value-of select="Titulo" /></p>
</xsl:template>
</xsl:stylesheet>

Recordemos que en el fichero XML (LibrosDeCasa.xml) debemos indicar el fichero de


transformación:

<!-- Fichero: LibrosDeCasa.xml -->


<?xml version="1.0" encoding="utf-8" ?>
<?xml-stylesheet type="text/xsl"
href="XSLTSencillo.xslt"?>
<Biblioteca>
......

Presentación y transformación de documentos XML - Página 15


Ejemplo 2
Vamos a generar como salida código HTML. La información a mostrar es el título del libro y
el autor. Usaremos el siguiente fichero XSLT:

<!-- Fichero: XSLTSencilloHTML.xslt -->


<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<HTML>
<HEAD><TITLE>Lista de libros</TITLE></HEAD>

Presentación y transformación de documentos XML - Página 16


<BODY BGCOLOR="#FFFF00">
<xsl:apply-templates />
</BODY>
</HTML>
</xsl:template>
<xsl:template match="Biblioteca">
<H2>Mis libros de casa:</H2>
<xsl:apply-templates />
<hr/>
</xsl:template>
<xsl:template match="Libro">
<P>
<xsl:apply-templates select="Titulo"/>
(<xsl:apply-templates select="Autor"/>)
</P>
</xsl:template>
<xsl:template match="Titulo">
<FONT COLOR="#0000FF">
<xsl:value-of select="." />
</FONT>
</xsl:template>
<xsl:template match="Autor">
<FONT COLOR="#FF0000">
<xsl:value-of select="." />
</FONT>
</xsl:template>
</xsl:stylesheet>

El fichero XML quedará ahora:

<!-- Fichero: LibrosDeCasa.xml -->


<?xml version="1.0" encoding="utf-8" ?>
<?xml-stylesheet type="text/xsl"
href="XSLTSencilloHTML.xslt"?>
<Biblioteca>
......

Presentación y transformación de documentos XML - Página 17


Ejemplo 3
En este ejemplo practicamos con la construcción iterativa xsl:for-each para mostrar un
informe detallado de cada libro.

<!-- Fichero: InformeGeneros.xslt -->


<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<HTML>

Presentación y transformación de documentos XML - Página 18


<HEAD><TITLE>Informe por géneros</TITLE></HEAD>
<BODY BGCOLOR="#D2D2D2">
<H2>Informe detallando los géneros</H2>
<xsl:for-each select="/Biblioteca/Libro">
<HR />
<B>Titulo: </B>
<I><xsl:value-of select="Titulo" /></I><BR />
<B>Autor : </B>
<I><xsl:value-of select="Autor" /></I><BR/>
<B>Temas: </B>
<xsl:for-each select="Generos/Genero">
<xsl:value-of select="." />,
</xsl:for-each>
<HR />
</xsl:for-each>
</BODY>
</HTML>
</xsl:template>
</xsl:stylesheet>

Presentación y transformación de documentos XML - Página 19


Ejemplo 4

Presentación y transformación de documentos XML - Página 20


En este ejemplo practicamos con la construcción de selección condicional xsl:if para
mostrar una lista de libros voluminosos.

<!-- Fichero: ListaVoluminosos.xslt -->


<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<!-- *********************************************** -->
<xsl:template match="/">
<HTML>
<xsl:apply-templates select="Biblioteca" />
</HTML>
</xsl:template>
<!-- *********************************************** -->
<xsl:template match="Biblioteca">
<HEAD><TITLE>Libros gordos</TITLE></HEAD>
<BODY BGCOLOR="#FAFAFA">
<H2>Mis libros voluminosos</H2>
<P>Los libros de la biblioteca que tienen más de
500 páginas son: </P>
<OL>
<xsl:apply-templates select="Libro" />
</OL>
</BODY>
</xsl:template>
<!-- *********************************************** -->
<xsl:template match="Libro">
<xsl:if test="NumPags &gt; 500">
<LI><B><xsl:value-of select="Titulo"/></B>
(<I><xsl:value-of select="Autor"/></I>):
<xsl:value-of select="NumPags"/> págs.
</LI>
</xsl:if>
</xsl:template>
<!-- *********************************************** -->
</xsl:stylesheet>

Presentación y transformación de documentos XML - Página 21


Si quisiéramos hacer más versátil esta hoja de estilo y quisiéramos que el número de páginas
mínimo fuera fácilmente modificable, de manera que solo hubiera que hacer un cambio para
generar una nueva lista podríamos usar una variable o, en la terminología adecuada, un
elemento xsl:parameter. Los cambios a realizar serían los siguientes:
- "Declarar" una variable y darle un valor:

<!-- Fichero: ListaVoluminosos.xslt -->


<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:param name="NumPagsVol" select="500" />
......

- Cambiar las referencias explícitas al valor por su nombre:


- Si va a mostrarse textualmente:

......

Presentación y transformación de documentos XML - Página 22


<P>Los libros de la biblioteca que tienen más de
<xsl:value-of select="$NumPagsVol"/>
páginas son: </P>
......

- Si se va a usar en una expresión:

......
<xsl:if test="NumPags &gt; $NumPagsVol">
......

Ejemplo 5
En este ejemplo practicamos con casi todos los elementos para construir una tabla que
recopila toda la información del documento XML.

<!-- Fichero: TablaResumen.xslt -->


<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<!-- *********************************************** -->
<xsl:template match="/">
<HTML>
<HEAD><TITLE>Tabla ordenada de libros</TITLE></HEAD>
<xsl:apply-templates select="Biblioteca" />
</HTML>
</xsl:template>
<!-- *********************************************** -->
<xsl:template match="Biblioteca">
<BODY BGCOLOR="#FAFAFA">
<H2 ALIGN="CENTER">Mis libros ordenados según
el número de paginas</H2>
<TABLE ALIGN="CENTER" BORDER="2">
<encabezado-tabla>
<TR BGCOLOR="#FFFF00"><TH>Titulo</TH><TH>Autor</TH>
<TH>Paginas</TH><TH>Precio</TH><TH>Disponible</TH>

Presentación y transformación de documentos XML - Página 23


<TH>Generos</TH></TR>
</encabezado-tabla>
<xsl:for-each select="Libro">
<xsl:sort select="NumPags" order="descending" />
<cuerpo-tabla>
<TR>
<TD><xsl:value-of select="Titulo"/></TD>
<TD><xsl:value-of select="Autor"/></TD>
<TD><xsl:value-of select="NumPags"/></TD>
<TD><xsl:value-of select="Precio"/></TD>
<TD ALIGN="CENTER">
<xsl:if test="@Disponible='true'">
<FONT COLOR="#00FF00"><B>SI</B></FONT>
</xsl:if>
<xsl:if test="@Disponible='false'">
<FONT COLOR="#FF0000"><B>NO</B></FONT>
</xsl:if>
</TD>
<TD>
<xsl:for-each select="Generos/Genero">
<xsl:value-of select="." /> -
</xsl:for-each>
</TD>
</TR>
</cuerpo-tabla>
</xsl:for-each>
</TABLE>
</BODY>
</xsl:template>
<!-- *********************************************** -->
</xsl:stylesheet>

Presentación y transformación de documentos XML - Página 24


Presentación y transformación de documentos XML - Página 25
XML en la plataforma .NET
© Francisco Cortijo Bon

Modelo de objetos de documento (DOM)


Introducción

Tipos de nodos

Acceso a los atributos

Conclusiones

Espacio de nombres System.Xml

La clase XmlDocument
Miembros de XmlDocument

Acceso a los atributos

Las clases XmlReader y XmlWriter

El espacio de nombres System.Xml.Xsl

El espacio de nombres System.Xml.XPath

XML en la plataforma .NET - Página 1


"Serialización" de documentos XML

Conjuntos de datos

XML en la plataforma .NET - Página 2


Modelo de objetos de documento (DOM)

Introducción
DOM (Document Object Model o modelo de objetos de documento) es un estándard de la
W3C que especifica la forma de acceder y manipular los datos de un documento XML
mediante un programa.

DOM especifica una representación en la memoria de un documento XML de manera


jerárquica mediante un árbol de nodos (elementos, comentarios, entidades, atributos, etc).

En la figura siguiente se muestra cómo se estructura la memoria cuando se leen los datos de la
biblioteca (XML) en la estructura DOM.

XML en la plataforma .NET - Página 3


XML en la plataforma .NET - Página 4
Dentro de la estructura de los documentos XML, cada elipse de esta ilustración representa un
nodo, que se denomina objeto XmlNode. El objeto XmlNode es el objeto básico del árbol
DOM. La clase XmlDocument, que extiende la clase XmlNode, admite métodos para
realizar operaciones en el documento en conjunto, por ejemplo, cargarlo en la memoria o
guardar el código XML en un archivo. Además, la clase XmlDocument proporciona un
medio para ver y manipular los nodos de todo el documento XML.

Tipos de nodos
A medida que el contenido XML se lee en el DOM las partes se traducen en nodos que
mantienen metadatos adicionales acerca de sí mismos, como su tipo y valores. Esto es,
cuando se leen varios datos, se asigna a cada nodo un tipo. Esto es importante ya que no todos
los nodos son del mismo tipo y e tipo determina las características y funcionalidad del nodo
(qué acciones pueden realizarse y qué propiedades pueden establecerse o recuperarse).

En la tabla siguiente se muestran algunos tipos de nodo, el objeto asociado a dicho tipo y una
breve dscripción.

Tipo de nodo DOM Objeto (clase .NET) Descripción


Document XmlDocument Contenedor de todos los
nodos del árbol. También
se conoce como la raíz del
documento, que no siempre
coincide con el elemento
raíz.
Element XmlElement Representa un nodo de
elemento.
Attr XmlAttribute Atributo de un elemento.
Comment XmlComment Nodo de comentario.
Text XmlText Texto que pertenece a un
elemento o atributo.
CDATASection XmlCDataSection Representa CDATA.
Los objetos DOM tienen un conjunto de métodos y propiedades, así como características
básicas y bien definidas. Algunas de estas características son:
- Un nodo tiene un único nodo primario, que se encuentra directamente encima de
él. El único nodos que no tiene un nodo primario es la raíz.

- La mayor parte de los nodos pueden tener varios nodos secundarios, que son los
que están situados inmediatamente debajo de ellos. Los tipos de nodo que pueden
tener nodos secundarios son Document, DocumentFragment,
EntityReference, Element y Attribute

XML en la plataforma .NET - Página 5


- Los nodos que se encuentran en el mismo nivel son nodos relacionados.

Acceso a los atributos


La forma de controlar los atributos es una característica de DOM. Los atributos no son
elementos secundarios de un elemento sino propiedades del elemento y están formados por un
par nombre-valor.

Es importante hacer esta distinción, debido a los métodos utilizados para desplazarse por los
nodos relacionados, principales y secundarios del DOM. Por ejemplo, los métodos
PreviousSibling y NextSibling no se utilizan para desplazarse de un elemento a un
atributo, ni entre atributos. En su lugar, un atributo es una propiedad de un elemento y
pertenece a un elemento, tiene una propiedad OwnerElement y no una propiedad
parentNode, y tiene métodos de desplazamiento distintos.

Conclusiones
DOM resulta útil para leer datos XML en la memoria y cambiar su estructura, agregar
o quitar nodos, o modificar los datos mantenidos en un nodo como en el texto contenido
en un elemento. No obstante, hay otras clases disponibles que son más rápidas que DOM en
otros escenarios:
- Para tener un acceso rápido, sólo hacia delante y sin almacenamiento en caché
a secuencias de XML, utilice XmlReader y XmlWriter.

- Si necesita acceso aleatorio con un modelo de cursor y XPath, utilice la clase


XPathNavigator.

XML en la plataforma .NET - Página 6


Espacio de nombres System.Xml

El espacio de nombres System.Xml proporciona compatibilidad basada en normas para


procesar XML. Se admiten las siguientes normas:
- XML 1.0: http://www.w3.org/TR/1998/REC-xml-19980210, incluida
compatibilidad con DTD.

- Espacios de nombres XML: http://www.w3.org/TR/REC-xml-names/, tanto a


nivel de secuencias como DOM.

- Esquemas XSD: http://www.w3.org/2001/XMLSchema

- Expresiones XPath: http://www.w3.org/TR/xpath

- Transformaciones XSLT: http://www.w3.org/TR/xslt

- Core DOM Level 1: http://www.w3.org/TR/REC-DOM-Level-1/

- Core DOM Level 2: http://www.w3.org/TR/DOM-Level-2/

Más información en:

System.Xml (Espacio de nombres)

La plataforma .NET proporciona soporte para XML en el espacio de nombres System.Xml


y los subespacios:
- System.Xml.Xsl.
El espacio de nombres System.Xml.Xsl proporciona compatibilidad con
transformaciones XSLT (Extensible Stylesheet Transformation). Admite la
Recomendación XSL Transformations (XSLT) Version 1.0 del Consorcio W3C (
www.w3.org/TR/xslt
).

Más información en:


System.Xml.Xsl (Espacio de nombres)

- System.Xml.XPath.
El espacio de nombres System.Xml.XPath contiene el motor de evaluación y

XML en la plataforma .NET - Página 7


el analizador XPath. Es compatible con la Recomendación XML Path Language
(XPath) Version 1.0 del Consorcio W3C (
www.w3.org/TR/xpath
).

Más información en:


System.Xml.XPath (Espacio de nombres)

- System.Xml.Schema.
El espacio de nombres System.Xml.Schema contiene las clases XML que
proporcionan compatibilidad basada en normas para los esquemas de XSD ó
lenguaje de definición de esquemas XML (
www.w3.org/XML/Schema
).

Más información en:


System.Xml.Schema (Espacio de nombres)

- System.Xml.Serialization.
El espacio de nombres System.Xml.Serialization contiene clases que se
utilizan para serializar objetos en secuencias o documentos con formato XML.

Más información en:


System.Xml.Serialization (Espacio de nombres)

System.Xml proporciona clases para crear, modificar y navegar en documentos XML.


También facilita el poder leer y escribir XML usando DOM proporcionando clases como
XPathNavigator , XmlDataDocument y XmlDocument. Además, permite
manipular elementos XML con las clases XmlElement, XmlAttribute, XmlComment,
etc.

XML en la plataforma .NET - Página 8


La clase base XmlNode representa un nodo individual de la jerarquía XML y proporciona
propiedades y métodos para:
- Recorrer jerárquicamente un documento XML.

- Consulta y selección de nodos.

- Modificar nodos.

- Borrar nodos.

Más información en:


XmlNode (Clase)

Breve descripción de las clases derivadas de XmlNode:


- XmlDocument. Representa un documento XML según el modelo DOM y
posibilita la exploración y edición del documento.

- XmlLinkedNode. Recupera el nodo que antecede o sigue al nodo actual. Es una


clase abstracta de la que deriva la clase XmlElement.

- XmlElement. Representa un elemento del árbol DOM. Los elementos pueden


tener atributos asociados. Dispone de muchos métodos para tener acceso a los
atributos (GetAttribute, SetAttribute, RemoveAttribute,
GetAttributeNode, etc.). Además, puede utilizar la propiedad Attributes
que devuelve una XmlAttributeCollection, que le permite tener acceso a
los atributos por nombre o por índice de la colección.

XML en la plataforma .NET - Página 9


- XmlAttribute. Representa un atributo de un XmlNode. Los valores válidos y
predeterminados del atributo se definen en una DTD o un esquema. Utilice la
propiedad OwnerElement para obtener el XmlElement al que pertenece el
atributo.

- XmlDataDocument. Extiende XmlDocument y permite que los datos


estructurados se almacenen, recuperen y manipulen mediante un DataSet
relacional. Esta clase permite que los componentes combinen vistas XML y
relacionales de los datos subyacentes.

XML en la plataforma .NET - Página 10


La clase XmlDocument

La clase XmlDocument implementa la clase XmlNode y representa un documento XML


completo según el modelo DOM y posibilita la exploración y edición del documento.

Cuando se instancia la clase XmlDocument puede leerse un documento XML utilizando el


método Load.

Dado que XmlDocument implementa la interfaz IXPathNavigable, también se puede


utilizar como documento de origen de la clase XslTransform.

Más información en:


XmlDocument (Clase)

Miembros de XmlDocument

Constructores
XmlDocument Inicializa una nueva instancia de la clase
XmlDocument.

Propiedades públicas
Attributes Obtiene un objeto
XmlAttributeCollection que
contiene los atributos de este nodo.
ChildNodes Obtiene todos los nodos secundarios del
nodo.
DocumentElement Obtiene el XmlElement raíz del
documento.
FirstChild Obtiene el primer nodo secundario del
nodo.
HasChildNodes Obtiene un valor que indica si este nodo
tiene nodos secundarios.
LatChild Obtiene el último nodo secundario del
nodo.
LocalName / Name Obtiene el nombre local/completo del
nodo.
NextSibling Obtiene el nodo inmediatamente siguiente

XML en la plataforma .NET - Página 11


Propiedades públicas
a éste.
NodeType Obtiene el tipo del nodo actual.
OwnerDocument Obtiene el XmlDocument al que
pertenece el nodo actual.
ParentNode Obtiene el nodo primario de este nodo
(para nodos que pueden tener nodos
primarios).
PreviousSibling Obtiene el nodo inmediatamente anterior
a éste.
Value Obtiene o establece el valor del nodo.

Métodos públicos
AppendChild Agrega el nodo especificado al final de la
lista de nodos secundarios de este nodo.
CreateAttribute Crea un XmlAttribute con el nombre
especificado.
CreateComment Crea un objeto XmlComment que contiene
los datos especificados.
CreateElement Crea un objeto XmlElement.
CreateNode Crea un objeto XmlNode.
CreateTextNode Crea un objeto XmlText con el texto
especificado.
GetElementsByTagName Devuelve un objeto XmlNodeList que
contiene una lista de todos los elementos
descendientes que coinciden con el
nombre especificado.
InsertAfter Inserta el nodo especificado
inmediatamente detrás del nodo de
referencia igualmente especificado.
InsertBefore Inserta el nodo especificado
inmediatamente antes del nodo de
referencia igualmente especificado.
Load Carga los datos XML especificados.

Nota: El método Load conserva siempre


bastante espacio en blanco. La propiedad
PreserveWhitespace determina si se
conserva o no espacio en blanco. El valor
predeterminado es false, es decir, el espacio
en blanco no se conserva.

XML en la plataforma .NET - Página 12


Métodos públicos
LoadXML Carga el documento XML desde la
cadena especificada.
PrependChild Agrega el nodo especificado al principio
de la lista de nodos secundarios de este
nodo.
RemoveAll Quita todos los atributos y nodos
secundarios del nodo actual.
RemoveChild Quita el nodo secundario especificado.
ReplaceChild Reemplaza un nodo secundario.
Save Guarda el documento XML en la
ubicación especificada.
SelectNodes Selecciona una lista de nodos que
coinciden con la expresión XPath.
SelectSingleNode Selecciona el primer XmlNode que
coincide con la expresión XPath.
El siguiente código copia en la consola el contenido del fichero XML
LibrosDeCasa.xml:

XmlDocument doc = new XmlDocument();


doc.Load ("../../LibrosDeCasa.xml");
doc.Save (Console.Out);

Ejemplo: cáculo de estadísticas


El siguiente código muestra algunas estadísticas calculadas a partir de los datos XML:

using System;
using System.IO;
using System.Xml;

class BibliotecaApp
{
static void Main(string[] args)
{
// Crear el documento en memoria y cargarlo
XmlDocument doc = new XmlDocument();
doc.Load ("../../LibrosDeCasa.xml");

XML en la plataforma .NET - Página 13


// Selección de libros usando expresion XPATH
XmlNodeList ListaLibros =
doc.SelectNodes ("/Biblioteca/Libro");
// Calcular el numero de libros
int nl = ListaLibros.Count;
Console.WriteLine ("Numero total de libros = {0}", nl);
double SumPrecio = 0.0;
double SumPags = 0;
// Calcular precio medio (Observar la seleccion
// que se realiza dentro de la seleccion)
foreach (XmlNode libro in ListaLibros)
{
string sP = libro.SelectSingleNode("Precio").InnerText;
double PrecioLibro = XmlConvert.ToDouble(sP);
SumPrecio += PrecioLibro;
}
Console.WriteLine (" Precio medio = {0} Euros",
SumPrecio / nl);
// Calcular tamaño medio (Observar que se hace
// una única selección -preferible-)
XmlNodeList ListaPrecios =
doc.SelectNodes ("/Biblioteca/Libro/NumPags");
for (int i=0; i < ListaPrecios.Count; i++)
{
int PagsLibro =
XmlConvert.ToInt16(ListaPrecios[i].InnerXml);
SumPags += PagsLibro;
}
Console.WriteLine (" Tamaño medio = {0} págs.",
SumPags / nl);

// Contar y mostrar los titulos de los libros


// disponibles. Observar la seleccion con atributo
string filtro = "/Biblioteca/Libro[@Disponible='true']";
XmlNodeList ListaDisponibles = doc.SelectNodes (filtro);
Console.WriteLine ("Libros disponibles = {0}",
ListaDisponibles.Count);
foreach (XmlNode LibroDisponible in ListaDisponibles)
{
string tit =
LibroDisponible.SelectSingleNode("Titulo").InnerText;
string aut =
LibroDisponible.SelectSingleNode("Autor").InnerText;
Console.Write (" " + tit);
Console.WriteLine (" (" + aut + ")");
}

XML en la plataforma .NET - Página 14


Console.ReadLine();
}
}

Acceso a los atributos


Cuando el nodo actual es un elemento, utilice el método HasAttribute para ver si hay
algún atributo asociado a dicho elemento. Una vez que se sabe que un elemento tiene
atributos, existen múltiples métodos de acceso a atributos. Para recuperar un único atributo de
un elemento, utilice los métodos GetAttribute y GetAttributeNode de
XmlElement, u obtenga todos los atributos en una colección. La obtención de la colección
resulta útil si es necesario recorrerla en iteración. Si desea obtener todos los atributos del
elemento, utilice la propiedad Attributes del elemento para recuperar todos los atributos
en una colección.

Recuperar todos los atributos en una colección.

Si desea obtener todos los atributos de un nodo de elemento en una colección, llame a la
propiedad XmlElement.Attributes. De este modo se obtiene la
XmlAttributeCollection que contiene todos los atributos de un elemento. Cada
elemento de la colección de atributos representa un nodo XmlAttribute. Para buscar el
número de atributos de un elemento, obtenga el XmlAttributeCollection y utilice la
propiedad Count para saber cuántos nodos XmlAttribute hay en la colección.

La información de una colección de atributos puede recuperarse por nombre (ver la línea de
código XmlAttribute atr = atrCol["ISBN"] en el siguiente ejemplo) o por
número de índice (sustituir la anterior por XmlAttribute atr = atrCol[1]).

XML en la plataforma .NET - Página 15


using System;
using System.IO;
using System.Xml;

class BibliotecaApp
{
static void Main(string[] args)
{
// Crear el documento en memoria
XmlDocument doc = new XmlDocument();
doc.LoadXml("<Libro Genero='Novela' " +
"ISBN='1-861001-57-5' " +
"Comentario='mal estado'>" +
"<Titulo>El oro del Rey</Titulo>" +
"<Precio>14.95</Precio>" +
"</Libro>");
// Colocarse en la raiz del documento.
XmlElement Raiz = doc.DocumentElement;
// Recuperar los atributos en una coleccion.
XmlAttributeCollection atrCol = Raiz.Attributes;
// De manera resumida:
// XmlAttributeCollection atrCol =
// doc.DocumentElement.Attributes;
// Mostrar los atributos de la coleccion iterando
// sobre los elementos de la coleccion.
Console.WriteLine("Atributos en la coleccion: ");
for (int i=0; i < atrCol.Count; i++)
{
Console.Write(" {0} = ", atrCol[i].Name);
Console.Write(" {0}", atrCol[i].Value);
Console.WriteLine();
}
// Recuperar un unico atributo (el llamado ISBN)
if (Raiz.HasAttribute("ISBN"))
{
// Seleccionar nombre
XmlAttribute atr = atrCol["ISBN"];
// Seleccionar valor
String ValorISBN = atr.InnerXml;
Console.WriteLine();
Console.Write ("Valor del atributo ISBN: ");
Console.WriteLine(ValorISBN);
}
Console.ReadLine();

XML en la plataforma .NET - Página 16


}
}

Recuperar un nodo de atributo individual.

Para recuperar un solo nodo de atributo de un elemento, se utiliza el método


XmlElement.GetAttributeNode. Este método devuelve un objeto de tipo
XmlAttribute. Una vez que se tiene el objeto XmlAttribute, todos los métodos y
propiedades de la clase de miembros XmlAttribute están disponibles en ese objeto, como
OwnerElement.

..........
// Colocarse en la raiz del documento.
XmlElement Raiz = doc.DocumentElement;
// Recuperar el atributo ISBN.
XmlAttribute atr = Raiz.GetAttributeNode("ISBN");

// Seleccionar valor
String ValorISBN = atr.InnerXml;
// Mostrar su valor
Console.Write ("Valor del atributo ISBN: ");
Console.WriteLine(ValorISBN);

// De otra manera:
String ValorISBNAlt = Raiz.GetAttribute("ISBN");
Console.Write ("Valor del atributo ISBN (alt): ");

XML en la plataforma .NET - Página 17


Console.WriteLine(ValorISBNAlt);
// Calcular y mostrar nodo propietario
XmlNode node= atr.OwnerElement;
String cad = node.Name;
Console.WriteLine ("Pertenece a un nodo: '{0}'", cad);
Console.ReadLine();
}
}

XML en la plataforma .NET - Página 18


Las clases XmlReader y XmlWriter

XmlReader es una clase base abstracta que proporciona acceso de sólo avance y de sólo
lectura sin almacenamiento en caché. Esto significa, por ejemplo, que no hay funciones para
editar los valores de un atributo o contenido de un elemento, ni la posibilidad de agregar y
quitar nodos. La lectura se realiza por el método de primero en profundidad (como se lee
textualmente XML).

El nodo actual hace referencia al nodo en el que está situado el lector. Para avanzar el lector,
utilice cualquiera de los métodos de lectura. Las propiedades reflejan el valor del nodo actual.

La clase XmlReader contiene métodos que permiten:


- Leer contenido XML cuando éste está disponible en su totalidad, por ejemplo, un
archivo de texto XML.

- Buscar la dimensión de la pila de elementos XML.

- Determinar si un elemento tiene contenido o está vacío.

- Leer y explorar atributos.

- Omitir elementos y su contenido.

La clase XmlReader tiene propiedades que devuelven información, como:


- Tipo y nombre del nodo actual.

- Contenido del nodo actual.

La clase XmlTextReader es una implementación de la clase base XmlReader que


permite tomar texto de entrada de flujos y ofrece métodos y propiedades para tratr elementos
y atributos además de posibilitar la validación del texto XML.

En las siguientes tablas resumimos algunos de los componentes más destacados de la clase
XmlTextReader:

Constructores
XmlTextReader Inicializa una nueva instancia de la clase
XmlTextReader.

XML en la plataforma .NET - Página 19


Propiedades públicas
EOF Obtiene un valor que indica si el lector
está situado al final de la secuencia.
HasAttributes Obtiene un valor que indica si el nodo
actual tiene atributos.
HasValue Obtiene un valor que indica si el nodo
actual puede tener una propiedad Value.
LocalName / Name Obtiene el nombre local/completo del
nodo actual.
NodeType Obtiene el tipo del nodo actual.
ReadState Obtiene el estado del lector (Closed,
EndOfFile, Error,etc.)
Value Obtiene el valor de texto del nodo actual.

Métodos públicos
Close Cambia la propiedad ReadState a
Closed.
MoveToElement Se desplaza hasta el elemento que
contiene el nodo de atributo actual.
Read Lee el siguiente nodo de la secuencia.
Skip Omite los nodos secundarios del nodo
actual.
Otras clases derivadas de XmlReader son:
- XmlNodeReader. Representa un lector que proporciona acceso rápido a datos
XML, sin almacenamiento en caché y con desplazamiento sólo hacia delante en
un XmlNode. XmlNodeReader puede leer un subárbol DOM XML. Esta clase
no admite la validación de DTD ni de esquemas. Para realizar la validación de
datos, utilice XmlValidatingReader.

- XmlValidatingReader. Representa un lector que proporciona validación de


esquemas para DTD, esquemas reducidos de datos XML (esquemas XDR) y
esquemas del lenguaje de definición de esquemas XML (esquemas XSD).

Más información en:


XmlReader (Clase)

Xmlwriter es una clase base abstracta que proporciona acceso de sólo avance y de sólo
escritura sin almacenamiento en caché para escribir código XML.

En la lista siguiente se muestra el propósito de los métodos y propiedades que incluye la clase

XML en la plataforma .NET - Página 20


XmlWriter:
- Especificar si se debe permitir el uso de espacios de nombres.

- Escribir código XML con un formato correcto.

- Administrar la salida, lo que incluye a los métodos para determinar su progreso,


con la propiedad WriteState.

- Escribir varios documentos en una secuencia de salida.

- Vaciar o cerrar la secuencia de salida.

- Escribir nombres válidos, nombres completos y símbolos (tokens) de nombres.

La clase XmlTextWriter es una implementación de la clase base XmlWriter que


incorpora propiedades y métodos para escribir XML sintácticamente correcto.

Más información en:


XmlWriter (Clase)

XML en la plataforma .NET - Página 21


El espacio de nombres System.Xml.Xsl

Copmo indicamos anteriormente System.Xml.Xsl proporciona clases y soporte para


realizar transformaciones XSLT. El objetivo de XSLT (Extensible Stylesheet Language
Transformation) es transformar el contenido de un documento XML de origen en otro
documento con un formato o estructura diferentes.

Más información en:


System.Xml.Xsl (Espacio de nombres)

La clase XslTransform (se encuentra en este espacio de nombres) es el procesador de


XSLT que implementa la funcionalidad de esta especificación. Otra clase útil de
System.Xml.Xsl es:
- XsltException. Excepción que se produce cuando ocurre algún error mientras
se procesa una transformación XSL (Extensible Stylesheet Language).

En la ilustración siguiente se muestra la arquitectura de transformación de .NET Framework.

La recomendación de XSLT utiliza XPath para seleccionar componentes de un documento

XML en la plataforma .NET - Página 22


XML. XPath es un lenguaje de consulta utilizado para explorar los nodos de un árbol de
documentos. Tal y como se muestra en el diagrama, la implementación de XPath en .NET
Framework se utiliza para seleccionar partes de XML almacenadas en varias clases, como
XmlDocument, XmlDataDocument y XPathDocument. XPathDocument es un
almacén de datos optimizado de XSLT y, si se utiliza con XslTransform, proporciona
transformaciones XSLT de alto rendimiento.

La transformación se aplica con el método Transform que transforma los datos XML
utilizando la hoja de estilos XSLT que se ha cargado.

Ejemplo 1

Empleando el fichero de transformación TransfSimple.xslt:

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/Biblioteca">
<ResumenBiblioteca>
<xsl:apply-templates />
</ResumenBiblioteca>
</xsl:template>
<xsl:template match="Libro">
<item>
<xsl:value-of select="Titulo" />
</item>
</xsl:template>
</xsl:stylesheet>

transformaremos el fichero LibrosDeCasa.xml de manera que el resultado de la


transformación se muestre en la consola.

using System;
using System.IO;
using System.Xml;
using System.Xml.Xsl;
class BibliotecaApp
{
static void Main(string[] args)
{
// Crear objeto XSLT y leer fichero XSLT.
XslTransform xslt = new XslTransform();
xslt.Load("../../TransfSimple.xslt");
// Crear objeto XML y leer fichero XML.

XML en la plataforma .NET - Página 23


XmlDocument doc = new XmlDocument();
doc.Load("../../LibrosDeCasa.xml");
// Aplicar la transformación y presentar el
// resultado en la consola.
xslt.Transform(doc, null, Console.Out, null);
Console.ReadLine();
}
}

Para que el resultado de la transformación se escriba en un fichero se emplea una versión


sobrecargada del método Transform:

.........
// Aplicar la transformación y guardar el
// resultado en un fichero.
xslt.Transform("../../LibrosDeCasa.xml",
"../../Resumen.xml", null);
.........

aunque el resultado, al igual que en la consola, no queda formateado correctamente:

XML en la plataforma .NET - Página 24


Podemos hacer que el resultado quede con el formato adecuado si empleamos un
XmlTextWriter y empleamos sobre él la propiedad Formatting. Por ejemplo:

using System;
using System.IO;
using System.Xml;
using System.Xml.Xsl;
class BibliotecaApp
{
static void Main(string[] args)
{
// Crear objeto XSLT y leer fichero XSLT.
XslTransform xslt = new XslTransform();
xslt.Load("../../TransfSimple.xslt");
// Crear objeto XML y leer fichero XML.
XmlDocument doc = new XmlDocument();
doc.Load("../../LibrosDeCasa.xml");
// Aplicar la transformación y presentar el
// resultado en la consola.
XmlTextWriter writer =
new XmlTextWriter (Console.Out);
writer.Formatting = Formatting.Indented;
writer.Indentation = 4;
writer.WriteStartDocument(true);
xslt.Transform(doc, null, writer, null);
Console.ReadLine();
}
}

que produce como resultado:

XML en la plataforma .NET - Página 25


Para que el resultado con formato se guarde en un fichero modificamos el programa para que
quede como sigue:

using System;
using System.IO;
using System.Xml;
using System.Xml.Xsl;
class BibliotecaApp
{
static void Main(string[] args)
{
// Crear objeto XSLT y leer fichero XSLT.
XslTransform xslt = new XslTransform();
xslt.Load("../../TransfSimple.xslt");
// Crear objeto XML y leer fichero XML.
XmlDocument doc = new XmlDocument();
doc.Load("../../LibrosDeCasa.xml");
XmlTextWriter rdo = new
XmlTextWriter("../../Resumen2.xml", null);
rdo.Formatting = Formatting.Indented;
rdo.WriteStartDocument(true);
xslt.Transform(doc, null, rdo, null);
Console.ReadLine();
}
}

y el resultado es:

XML en la plataforma .NET - Página 26


La modificación propuesta ahora:

......
XmlTextWriter rdo =
new XmlTextWriter("../../Resumen3.xml",
System.Text.Encoding.UTF8);
......

hace que se modifique el prólogo del fichero XML incorporando la codificación UTF-8:

XML en la plataforma .NET - Página 27


El espacio de nombres System.Xml.XPath

El espacio de nombres System.Xml.XPath contiene el motor de evaluación y el


analizador XPath. Es compatible con la Recomendación XML Path Language (XPath)
Version 1.0 del Consorcio W3C (www.w3.org/TR/xpath).

Las clases más importantes proporcionadas en el espacio de nombres System.Xml.XPath


son:
- XPathDocument. Proporciona una caché rápida y de sólo lectura para el
procesamiento de documentos XML mediante XSLT. Esta clase está optimizada
para el procesamiento XSLT y el modelo de datos XPath.

- XPathNavigator. Lee datos de cualquier almacén de datos mediante un


modelo de cursor.

- XPathNodeIterator. Proporciona un iterador para un conjunto de nodos


seleccionados.

Más información en:


System.Xml.XPath (Espacio de nombres)

El siguiente ejemplo usa el modelo de cursor para calcular el precio medio de los libros.
Utilice el XPathNodeIterator para establecer una iteración en un conjunto de nodos.

using System;
using System.IO;
using System.Xml;
using System.Xml.XPath;
class BibliotecaApp
{
static void Main(string[] args)
{
// Abre para lectura el fichero XML
XPathDocument doc =
new XPathDocument ("../../LibrosDeCasa.xml");
// Crea un objeto XPathNavigator (nav) para
// desplazarse por doc
XPathNavigator nav = doc.CreateNavigator();
// Selecciona un conjunto de nodos utilizando la

XML en la plataforma .NET - Página 28


// expresión XPath especificada.
XPathNodeIterator it =
nav.Select("/Biblioteca/Libro/Precio");
int nl = it.Count;
Console.WriteLine ("Numero total de libros= {0}",nl);
// Iterador con MoveNext()
double SumPrecio1 = 0.0;
while (it.MoveNext())
SumPrecio1 +=
XmlConvert.ToDouble(it.Current.Value);
Console.WriteLine (" Precio medio (1) = {0} Euros",
SumPrecio1 / nl);
Console.ReadLine();
}
}

El método Evaluate evalúa la cadena que representa a una expresión XPath y devuelve el
resultado de tipo (número, valor booleano, cadena o conjunto de nodos).

using System;
using System.IO;
using System.Xml;
using System.Xml.XPath;
class BibliotecaApp
{
static void Main(string[] args)
{
// Abre para lectura el fichero XML
XPathDocument doc =
new XPathDocument ("../../LibrosDeCasa.xml");
// Crea un objeto XPathNavigator (nav) para
// desplazarse por doc
XPathNavigator nav = doc.CreateNavigator();
// Selecciona un conjunto de nodos utilizando la
// expresión XPath especificada.
XPathNodeIterator it =
nav.Select("/Biblioteca/Libro/Precio");
int nl = it.Count;
Console.WriteLine ("Numero total de libros= {0}",nl);
// Compila una cadena que representa a una expresión
// XPath y devuelve una expresion XPath
XPathExpression expr =
nav.Compile("sum(/Biblioteca/Libro/Precio)");
// Evalua la expresion
double SumPrecio2 = (double) nav.Evaluate(expr);

XML en la plataforma .NET - Página 29


Console.WriteLine (" Precio medio (2) = {0} Euros",
SumPrecio2 / nl);
Console.ReadLine();
}
}

El siguiente ejemplo recorre el fichero de libros mostrando la lista de títulos y número de


páginas. Despues muestra el número medio de páginas.

using System;
using System.IO;
using System.Xml;
using System.Xml.XPath;
class BibliotecaApp2
{
static void Main(string[] args)
{
Console.WriteLine ("Lista de libros\n");
// Lee en doc un fichero XML
XmlDocument doc = new XmlDocument ();
doc.Load("../../MisLibros.xml");
// Crea un objeto XPathNavigator (nav) para
// desplazarse por doc
XPathNavigator nav = doc.CreateNavigator();
// Accede al primer hijo de "doc": <Biblioteca>
nav.MoveToFirstChild();
int nl= 1;
int sum = 0;
// Accede al primer <Libro>
nav.MoveToFirstChild();
// Escibe los datos del primer libro
Console.Write ("Libro {0}: ", nl);
// Accede y pinta el primer campo (<Titulo>)
nav.MoveToFirstChild();
Console.Write (nav.Value);
// Saltar campo <Autor> y colocarse en <NumPags>
for (int i=0; i<2; i++)
nav.MoveToNext();
Console.WriteLine (" ({0} págs.)", nav.Value);
sum += XmlConvert.ToInt16(nav.Value);
// Volver al nodo <Libro>

XML en la plataforma .NET - Página 30


nav.MoveToParent();

// Repetir para los restantes nodos <Libro>


while (nav.MoveToNext())
{
Console.Write ("Libro {0}: ", ++nl);
// Accede y pinta el primer campo <Titulo>
nav.MoveToFirstChild();
Console.Write (nav.Value);
// Saltar campo <Autor> y colocarse en <NumPags>
for (int i=0; i<2; i++)
nav.MoveToNext();
Console.WriteLine (" ({0} págs.)", nav.Value);
sum += XmlConvert.ToInt16(nav.Value);
// Volver al nodo <Libro>
nav.MoveToParent();
}
Console.WriteLine ("\nTotal de páginas = {0}", sum);
Console.WriteLine ("Tamaño medio = {0}",
(float)sum / nl);
Console.ReadLine();
}
}

XML en la plataforma .NET - Página 31


"Serialización" de documentos XML

Introducción
El objetivo primario de la serialización en .NET es permitir la conversión de documentos
XML y flujos (streams) en objetos CLR y viceversa. Esta conversión se realizará en tiempo
de ejecución. Esta conversión supone que la manipulación de los objetos será más sencilla
que hacerlo con otras técnicas comunes (programas que hacen uso de DOM, por ejemplo).

En lugar de serialización debía llamarse transformación:


- No serializa cualquier objeto CLR en XML.

- Está diseñada para transformar clases a esquemas e instancias de clases a


instancias de esquemas.

- El objetivo es representar cualquier XML, no cualquier objeto.

La clase fundamental para esta tarea es XmlSerializer. Esta clase se emplea para
serializar y deserializar objetos en y desde documentos XML. XmlSerializer permite
controlar el modo en que se codifican los objetos en XML.

Los métodos fundamentales de la clase XmlSerializer son: Serialize y


Deserialize. Otro método importante es CanDeserialize.

Más información en:


XmlSerializer (Clase)

using System;
using System.IO;
using System.Xml.Serialization;
namespace XSDSample
{
public class Test
{
public String cad;
}
class SerialApp {

XML en la plataforma .NET - Página 32


static void Main(string[] args)
{
Test t = new Test();
t.cad = "Cadena de prueba";
XmlSerializer ser = new XmlSerializer (typeof(Test));
FileStream stream = new FileStream ("test.xml",
FileMode.OpenOrCreate);
ser.Serialize (stream, t);
}
}
}

Algunos puntos a tener en cuenta son:


- Solo pueden serializarse las clases que tienen un constructor público y
predeterminado.

// Clase serializable
public class Test
{
public Test() {} // Igual que no ponerlo
public String cad;
}
// Clase NO serializable
public class Test2
{
public Test2(String cadena)
{
this.cad = cadena;
}
public String cad;
}

XML en la plataforma .NET - Página 33


- Solo pueden serializarse campos y propiedades public.
Por ejemplo, la siguiente clase tiene todos sus miembros private:

// Clase serializable sin miembros serializables


public class Cliente
{
private String Nombre;
private String Direccion;
private String Telefono;
}

y al serializarla se obtiene el siguiente resultado:

<?xml version="1.0"?>
<Cliente
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
/>

Sin embargo, cuando los campos de la clase son public

// Clase serializable con miembros serializables


public class Cliente
{
public String Nombre;
public String Direccion;
public String Telefono;
}
.....
Cliente c = new Cliente();
c.Nombre = "Pepe";
c.Direccion = "Casa de Pepe";
c.Telefono = "123456789";
XmlSerializer ser = new XmlSerializer (typeof(Cliente));
FileStream stream = new FileStream ("cliente.xml",
FileMode.OpenOrCreate);
ser.Serialize (stream, c);
.....

el resultado es muy diferente:

<?xml version="1.0"?>
<Cliente

XML en la plataforma .NET - Página 34


xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Nombre>Pepe</Nombre>
<Direccion>Casa de Pepe</Direccion>
<Telefono>123456789</Telefono>
</Cliente>

- Los campos de solo lectura (readonly) y las propiedades no son serializables.

- Los métodos y cualquier información de tipos no son serializables.

Ejemplo

using System;
using System.IO;
using System.Xml;
using System.Xml.Serialization;
namespace SerDeserSample
{
public class Cliente
{
public string Nombre;
public string Direccion;
public string Telefono;
public override string ToString() {
string s1 = "Un cliente:"+"\n";
string s2 = " Nombre: " + this.Nombre + "\n";
string s3 = " Dirección: " + this.Direccion + "\n";
string s4 = " Teléfono: " + this.Telefono+ "\n";
return (s1+s2+s3+s4);
}
}
class SerDeserSampleApp {
static void Main(string[] args)
{
Cliente c = new Cliente();
c.Nombre = "Juan";
c.Direccion = "Casa de Juan S/N";
c.Telefono = "333444555";
Console.WriteLine ("Antes de guardar");
Console.WriteLine (c);
// Serializar
XmlSerializer ser = new
XmlSerializer (typeof(Cliente));
FileStream OStream = new FileStream ("Juan.xml",
FileMode.OpenOrCreate);
ser.Serialize (OStream, c);

XML en la plataforma .NET - Página 35


OStream.Close();
// Deserializar
Cliente c2;
XmlSerializer ser2 = new
XmlSerializer(typeof(Cliente));
FileStream IStream = new
FileStream("Juan.xml", FileMode.Open);
XmlReader reader = new XmlTextReader(IStream);
if(ser2.CanDeserialize(reader)) {
c2 = (Cliente) ser2.Deserialize (reader);
Console.WriteLine ("Despues de recuperar");
Console.WriteLine (c2);
}
else
Console.WriteLine("No puedo deserializar");
IStream.Close();
Console.ReadLine();
} // Main
} // class SerDeserSampleApp
} // manespace SerDeserSample

El fichero Juan.xml contiene:

<?xml version="1.0"?>
<Cliente
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Nombre>Juan</Nombre>
<Direccion>Casa de Juan S/N</Direccion>
<Telefono>333444555</Telefono>
</Cliente>

y en la consola se muestra este resultado:

XML en la plataforma .NET - Página 36


Personalizar la serialización
Pueden emplearse atributos en las clases y sus miembros que modifican el XML resultante
de la serialización.
- Los atributos XmlRoot y XmlElement se emplean para especificar el nombre
de un elemento XML. Si no se especifican, las etiquetas del documento XML son
los nombres de los campos de la clase.
Observar el siguiente ejemplo:

using System;
using System.IO;
using System.Xml;
using System.Xml.Serialization;
namespace SerDeserSample
{
[XmlRoot("cliente")]
public class Cliente
{
public string Nombre;
public string Direccion;
public string Telefono;
public override string ToString() {
string s1 = "Un cliente:"+"\n";
string s2 = " Nombre: " + this.Nombre + "\n";
string s3 = " Dirección: " + this.Direccion + "\n";
string s4 = " Teléfono: " + this.Telefono+ "\n";
return (s1+s2+s3+s4);

XML en la plataforma .NET - Página 37


}
}
[XmlRoot("cliente")]
public class BuenCliente {
public string Telefono;
public string Direccion;
public string Nombre;
public override string ToString() {
string s1 = "Un buen cliente:"+"\n";
string s2 = " Nombre: " + this.Nombre + "\n";
string s3 = " Dirección: " + this.Direccion + "\n";
string s4 = " Teléfono: " + this.Telefono+ "\n";
return (s1+s2+s3+s4);
}
}
class SerDeserSampleApp {
static void Main(string[] args)
{
Cliente c = new Cliente();
c.Nombre = "Pepe";
c.Direccion = "Casa de Pepe";
c.Telefono = "123456789";
Console.WriteLine (c);
// Serializar
XmlSerializer ser = new
XmlSerializer (typeof(Cliente));
FileStream OStream = new FileStream ("cli.xml",
FileMode.OpenOrCreate);
ser.Serialize (OStream, c);
OStream.Close();
// Deserializar
BuenCliente bc;
XmlSerializer ser2 = new
XmlSerializer(typeof(BuenCliente));
FileStream IStream = new
FileStream("cli.xml", FileMode.Open);
XmlReader reader = new XmlTextReader(IStream);
if(ser2.CanDeserialize(reader)) {
bc = (BuenCliente) ser2.Deserialize (reader);
Console.WriteLine (bc);
}
else
Console.WriteLine("No puedo deserializar");
IStream.Close();
Console.ReadLine();
} // Main
} // class SerDeserSampleApp

XML en la plataforma .NET - Página 38


} // manespace SerDeserSample

El fichero cli.xml contiene:

<?xml version="1.0"?>
<cliente
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Nombre>Pepe</Nombre>
<Direccion>Casa de Pepe</Direccion>
<Telefono>123456789</Telefono>
</cliente>

y en la consola se muestra este resultado:

Hay que tener ciertas precauciones en el proceso de deserialización, ya que éste


no es directo:
- La clase destino, si es diferente a la origen, debe conocer el nombre del elemento
raíz del XML. Por ejemplo, en la siguiente situación no puede deserializarse hacia
la clase BuenCliente:

public class Cliente {


public string Nombre;
public string Direccion;
public string Telefono;
......
}
public class BuenCliente {

XML en la plataforma .NET - Página 39


public string Telefono;
public string Direccion;
public string Nombre;
......
}
Para poder hacerlo podríamos añadir un atributo a la clase destino:

[XmlRoot("Cliente")]
public class BuenCliente {
public string Telefono;
......
}
o bien homogeneizar las clases origen y destino:

[XmlRoot("cliente")]
public class BuenCliente {
public string Nombre;
......
}
[XmlRoot("cliente")]
public class BuenCliente {
public string Telefono;
......
}

- El mismo criterio se sigue para los demás elementos XML que se copian a la clase
destino: o coinciden en nombre con los campos de la clase o se especifica un
atributo XmlElement en la declaración de la clase:

[XmlRoot("cliente")]
public class Cliente {
public string Nombre;
public string Direccion;
public string Telefono;
......
}
[XmlRoot("cliente")]
public class BuenCliente {
[XmlElement("Telefono")]
public string Tfno;
public string Dir;
[XmlElement("Nombre")]
public string Nbre;
......
}
En este ejemplo sólo se deserializan los elementos Telefono y Nombre (del
documento XML) en los campos Tfno y Nbre (de la clase BuenCliente).

XML en la plataforma .NET - Página 40


- Puede modificarse el espacio de nombres predeterminado con el parámetro
Namespace

[XmlRoot("MiCliente", Namespace="http://rocco.ugr.es")]
public class Cliente
{
public string Nombre;
public string Direccion;
public string Telefono;
}

Al serializar esta clase obtenemos (fichero cli3.xml):

<?xml version="1.0"?>
<MiCliente
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://rocco.ugr.es">
<Nombre>Pepe</Nombre>
<Direccion>Casa de Pepe</Direccion>
<Telefono>123456789</Telefono>
</MiCliente>

- Puede modificarse el espacio de nombres para algunos elementos:

[XmlRoot("MiCliente",
Namespace="http://rocco.ugr.es/Clis")]
public class Cliente {
public string Nombre;
[XmlElement(Namespace="http://elvex.ugr.es/Dirs")]
public TDireccion Direccion;
public string Telefono;
}
public class TDireccion {
public string Calle;
public int Numero;
public string Ciudad;
public string CP;
}
......
Cliente c = new Cliente();
c.Direccion = new TDireccion();
c.Nombre = "Pepe";
c.Direccion.Calle = "Calle Fina";
c.Direccion.Numero = 4;
c.Direccion.Ciudad = "Metrópolis";
c.Direccion.CP = "12345";
c.Telefono = "123456789";

XML en la plataforma .NET - Página 41


......

Al serializar esta clase obtenemos (fichero cli4.xml):

<?xml version="1.0"?>
<MiCliente
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://rocco.ugr.es/Clis">
<Nombre>Pepe</Nombre>
<Direccion
xmlns="http://elvex.ugr.es/Dirs">
<Calle>Calle Fina</Calle>
<Numero>4</Numero>
<Ciudad>Metrópolis</Ciudad>
<CP>12345</CP>
</Direccion>
<Telefono>123456789</Telefono>
</MiCliente>

- Un elemento puede serializarse como un atributo XML.

[XmlRoot("MiCliente",
Namespace="http://rocco.ugr.es/Clis")]
public class Cliente {
public string Nombre;
[XmlElement(Namespace="http://elvex.ugr.es/Dirs")]
public TDireccion Direccion;
[XmlAttribute]
public string Telefono;
}
public class TDireccion {
public string Calle;
public int Numero;
public string Ciudad;
[XmlAttribute]
public string CP;
}

Al serializar esta clase obtenemos (fichero cli5.xml):

<?xml version="1.0"?>
<MiCliente
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
Telefono="123456789"

XML en la plataforma .NET - Página 42


xmlns="http://rocco.ugr.es/Clis">
<Nombre>Pepe</Nombre>
<Direccion
CP="12345"
xmlns="http://elvex.ugr.es/Dirs">
<Calle>Calle Fina</Calle>
<Numero>4</Numero>
<Ciudad>Metrópolis</Ciudad>
</Direccion>
</MiCliente>

- Al serializar vectores cada entrada del vector se transforma en un elemento de un


elemento complejo:

public string[] Telefono;

<Telefono>
<string>123456789</string>
<string>987654321</string>
......
</Telefono>

o se puede cambiar el nombre al conjunto y a cada elemento:

[XmlArray("TelefonosContacto")]
[XmlArrayItem("NumTelefono")]
public string[] Telefono;

<TelefonosContacto>
<NumTelefono>123456789</NumTelefono>
<NumTelefono>987654321</NumTelefono>
......
</TelefonosContacto>

XML en la plataforma .NET - Página 43


Conjuntos de datos

DataSet myDataSet = new DataSet();


...
// -------------------------------------------
// Generación de un documento XML y su esquema
// XSD a partir de un DataSet
// -------------------------------------------
myDataSet.Namespace = "http://elvex.ugr.es/";
myDataSet.DataSetName = "datos";
myDataSet.WriteXml("fichero.xml");
myDataSet.WriteXmlSchema("fichero.xsd");
// Lectura de un documento XML
// ---------------------------
myDataSet.ReadXml("fichero.xml");
// Validación de un documento XML
// ------------------------------
XmlDocument doc = new XmlDocument();
XmlTextReader tr = new XmlTextReader("fichero.xml");
XmlValidatingReader vr = new XmlValidatingReader(tr);
XmlSchemaCollection collection = new XmlSchemaCollection();
collection.Add("http://elvex.ugr.es/","fichero.xsd");
vr.Schemas.Add(collection);
vr.ValidationType = ValidationType.Schema;
reader.ValidationEventHandler +=
new ValidationEventHandler (this.ValidationEventHandle);
doc.Load(vr);

// Errores de validación (callback)


private void ValidationEventHandle (object sender,
ValidationEventArgs args)
{
error = true;
Console.WriteLine("\r\n\tError de validación: "
+ args.Message );
}

XML en la plataforma .NET - Página 44

También podría gustarte