FANDOM


XML de trabajoEditar

Como en el capítulo anterior, vamos a trabajar con el mismo documento XML durante éste. Se trata del siguiente:

<?xml version="1.0" encoding="iso-8859-15"?>
<pelicula titulo="Brazil" estreno="1985" minutos="132">
	<direccion>
		<director nombre="Terry" apellidos="Gilliam"/>
	</direccion>
	<produccion>
		<productor nombre="Patrick" apellidos="Cassavetti"/>
		<productor nombre="Arnon" apellidos="Milchan"/>
	</produccion>
	<guion>
		<guionista nombre="Terry" apellidos="Gilliam"/>
		<guionista nombre="Tom" apellidos="Stoppard"/>
		<guionista nombre="Charles" apellidos="McKeown"/>
	</guion>
	<reparto>
		<interprete nombre="Jonathan" apellidos="Pryce"
			papel="protagonista"/>
		<interprete nombre="Robert" apellidos="De Niro"
			papel="protagonista"/>
		<interprete nombre="Kim" apellidos="Greist"
			papel="protagonista"/>
		<interprete nombre="Michael" apellidos="Palin"
			papel="secundario"/>
		<interprete nombre="Ian" apellidos="Holm"
			papel="secundario"/>
		<interprete nombre="Bob" apellidos="Hoskins"
			papel="secundario"/>
	</reparto>
	<esloganes>
		<eslogan>
			Vuelos fantásticos. La pesadilla de la
			realidad. Ataques terroristas. Compras
			a media noche. Amor verdadero. Y fontanería
			creativa.
		</eslogan>
	</esloganes>
</pelicula>

Validación con DTDEditar

Supongamos que queremos validar el documento XML con el que vamos a trabajar en este capítulo utilizando la siguiente DTD:

<!ELEMENT pelicula
	(direccion?,produccion?,guion?,reparto?,esloganes?)>
<!ATTLIST pelicula titulo CDATA #REQUIRED>
<!ATTLIST pelicula estreno CDATA #IMPLIED>
<!ATTLIST pelicula minutos CDATA #IMPLIED>
 
<!ELEMENT direccion (director+)>
<!ELEMENT director EMPTY>
<!ATTLIST director nombre CDATA #REQUIRED>
<!ATTLIST director apellidos CDATA #REQUIRED>
 
<!ELEMENT produccion (productor+)>
<!ELEMENT productor EMPTY>
<!ATTLIST productor nombre CDATA #REQUIRED>
<!ATTLIST productor apellidos CDATA #REQUIRED>
 
<!ELEMENT guion (guionista+)>
<!ELEMENT guionista EMPTY>
<!ATTLIST guionista nombre CDATA #REQUIRED>
<!ATTLIST guionista apellidos CDATA #REQUIRED>
 
<!ELEMENT reparto (interprete+)>
<!ELEMENT interprete EMPTY>
<!ATTLIST interprete nombre CDATA #REQUIRED>
<!ATTLIST interprete apellidos CDATA #REQUIRED>
<!ATTLIST interprete papel
	(protagonista | secundario) #REQUIRED>
 
<!ELEMENT esloganes (eslogan+)>
<!ELEMENT eslogan (#PCDATA)>

El siguiente programa realiza la validación del documento XML usando la DTD anterior:

using System;
using System.Xml;
using System.Xml.Schema;
 
class MainClass
{
	public static void Main(string[] args)
	{
		string sRuta = "c:\\xml\\";
		// string sRuta = "/home/andy/xml/";
 
		try
		{
			XmlReaderSettings opciones = new XmlReaderSettings();
			opciones.DtdProcessing = DtdProcessing.Parse;
			opciones.ValidationType = ValidationType.DTD;
			opciones.ValidationEventHandler += new ValidationEventHandler(
				GestorErrorValidacion);
 
			XmlReader reader = XmlReader.Create(sRuta + "brazil.xml", opciones);
 
			while(reader.Read());
		}
 
		catch(Exception e)
		{
			Console.WriteLine("Error: '{0}'", e);
		}
 
		Console.Write("Pulse una tecla para continuar...");
		Console.ReadKey(true);
	}
 
	// Display any validation errors.
	private static void GestorErrorValidacion(object sender, ValidationEventArgs e)
	{
		Console.WriteLine("Error de validación: {0}", e.Message);
	}
}

El documento XML debe ser modificado, incluyendo el siguiente código en la cabecera del mismo:

...
<!DOCTYPE pelicula SYSTEM "filmoteca.dtd">
...

Validación con esquemasEditar

Como en la sección anterior, pero en lugar de una DTD trabajaremos con el siguiente esquema:

<?xml version="1.0"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema">
	<element name="pelicula">
		<complexType>
			<sequence>
				<element name="direccion">
					<complexType>
						<sequence>
							<element name="director" maxOccurs="unbounded">
								<complexType>
									<attribute name="nombre" type="string" use="required"/>
									<attribute name="apellidos" type="string" use="required"/>
								</complexType>
							</element>
						</sequence>
					</complexType>
				</element>
				<element name="produccion">
					<complexType>
						<sequence>
							<element name="productor" maxOccurs="unbounded">
								<complexType>
									<attribute name="nombre" type="string" use="required"/>
									<attribute name="apellidos" type="string" use="required"/>
								</complexType>
							</element>
						</sequence>
					</complexType>
				</element>
				<element name="guion">
					<complexType>
						<sequence>
							<element name="guionista" maxOccurs="unbounded">
								<complexType>
									<attribute name="nombre" type="string" use="required"/>
									<attribute name="apellidos" type="string" use="required"/>
								</complexType>
							</element>
						</sequence>
					</complexType>
				</element>
				<element name="reparto">
					<complexType>
						<sequence>
							<element name="interprete" maxOccurs="unbounded">
								<complexType>
									<attribute name="nombre" type="string" use="required"/>
									<attribute name="apellidos" type="string" use="required"/>
									<attribute name="papel" type="string" use="required"/>
								</complexType>
							</element>
						</sequence>
					</complexType>
				</element>
				<element name="esloganes">
					<complexType>
						<sequence>
							<element name="eslogan" type="string" maxOccurs="unbounded"/>
						</sequence>
					</complexType>
				</element>
			</sequence>
			<attribute name="titulo" type="string" use="required"/>
			<attribute name="estreno" type="integer" use="optional"/>
			<attribute name="minutos" type="integer" use="optional"/>
		</complexType>
	</element>
</schema>

Puedes utilizar el mismo programa mostrado en el apartado anterior, con algunas modificaciones.

using System;
using System.Xml;
using System.Xml.Schema;
 
class MainClass
{
	public static void Main(string[] args)
	{
		string sRuta = "c:\\xml\\";
		// string sRuta = "/home/andy/xml/";
 
		try
		{
			XmlReaderSettings opciones = new XmlReaderSettings();
			opciones.ValidationType = ValidationType.Schema;
			opciones.ValidationFlags |= XmlSchemaValidationFlags.ProcessSchemaLocation;
			opciones.ValidationFlags |= XmlSchemaValidationFlags.ReportValidationWarnings;
			opciones.ValidationEventHandler += new ValidationEventHandler(GestorErrorValidacion);
 
			XmlReader reader = XmlReader.Create(sRuta + "brazil.xml", opciones);
 
			while(reader.Read());
		}
 
		catch(Exception e)
		{
			Console.WriteLine("Error: '{0}'", e);
		}
 
		Console.Write("Pulse una tecla para continuar...");
		Console.ReadKey(true);
	}
 
	private static void GestorErrorValidacion(object sender, ValidationEventArgs e)
	{
		Console.WriteLine("Error de validación: {0}", e.Message);
	}
}

En este caso, el documento XML ha de ser modificado para que contenga el siguiente código en su cabecera:

...
<pelicula titulo="Brazil" estreno="1985" minutos="132"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:noNamespaceSchemaLocation="filmoteca.xsd">
...

Esto debe ir en lugar de:

...
<!DOCTYPE pelicula SYSTEM "filmoteca.dtd">
...

Creación de documentosEditar

Se puede crear un documento XML desde cero, utilizando el lenguaje de programación de nuestra elección:

using System;
using System.Xml;
 
class MainClass
{
	public static void Main(string[] args)
	{
		try
		{
			string sXML = "";
			string sTitulo = "Brazil";
 
			sXML = "<pelicula titulo=\"" + sTitulo + "\"></pelicula>";
 
			XmlDocument doc = new XmlDocument();
			doc.LoadXml(sXML);
 
			Console.WriteLine(doc.OuterXml);
		}
 
		catch(Exception e)
		{
			Console.WriteLine("Error: '{0}'", e);
		}
  }
}

Tras las creación, es posible trabajar con el documento recién creado, añadiendo nuevos elementos:

using System;
using System.Xml;
using System.Xml.Schema;
 
class MainClass
{
	public static void Main(string[] args)
	{
		string sRuta = "c:\\xml\\";
		// string sRuta = "/home/andy/xml/";
 
		try
		{
			string sXML = "";
			string sTitulo = "Brazil";
 
			sXML = "<pelicula titulo=\"" + sTitulo + "\"></pelicula>";
 
			XmlDocument doc = new XmlDocument();
			doc.LoadXml(sXML);
 
			Console.WriteLine("Antes: " + doc.OuterXml);
 
			XmlElement elemento;
			elemento = doc.CreateElement("direccion");
			doc.DocumentElement.AppendChild(elemento);
 
			Console.WriteLine("Después: " + doc.OuterXml);
		}
 
		catch(Exception e)
		{
			Console.WriteLine("Error: '{0}'", e);
		}
 
		Console.Write("Pulse una tecla para continuar...");
		Console.ReadKey(true);
	}
}

Inserción de atributosEditar

Una vez creado el documento XML utilizando DOM, es posible realizar muchas operaciones con él. Por ejemplo, se pueden añadir atributos a documentos ya existentes. El siguiente programa sirve para tal fin:

using System;
using System.Xml;
using System.Xml.Schema;
 
class MainClass
{
	public static void Main(string[] args)
	{
		string sRuta = "c:\\xml\\";
		// string sRuta = "/home/andy/xml/";
 
		try
		{
			XmlDocument doc = new XmlDocument();
			XmlElement elemento;
			elemento = doc.CreateElement("pelicula");
 
			XmlAttribute atr;
			atr = doc.CreateAttribute("titulo");
			atr.Value = "Brazil";
 
			elemento.SetAttributeNode(atr);
			doc.AppendChild(elemento);
 
			Console.WriteLine(doc.OuterXml);
		}
 
		catch(Exception e)
		{
			Console.WriteLine("Error: '{0}'", e);
		}
 
		Console.Write("Pulse una tecla para continuar...");
		Console.ReadKey(true);
	}
}

Con lo visto hasta ahora podemos crear de la nada el documento de trabajo de este capítulo:

using System;
using System.Xml;
using System.Xml.Schema;
 
class MainClass
{
	public static void Main(string[] args)
	{
		string sRuta = "c:\\xml\\";
		// string sRuta = "/home/andy/xml/";
 
		try
		{
			XmlDocument doc = new XmlDocument();
 
			XmlElement elemento;
			XmlAttribute atr;
 
			// Creación del elemento raíz.
			elemento = doc.CreateElement("pelicula");
 
			atr = doc.CreateAttribute("titulo");
			atr.Value = "Brazil";
			elemento.SetAttributeNode(atr);
 
			atr = doc.CreateAttribute("estreno");
			atr.Value = "1985";
			elemento.SetAttributeNode(atr);
 
			atr = doc.CreateAttribute("minutos");
			atr.Value = "132";
			elemento.SetAttributeNode(atr);
 
			doc.AppendChild(elemento);
 
			// Creación de los eslóganes.
			elemento = doc.CreateElement("esloganes");
			doc.DocumentElement.AppendChild(elemento);
 
			// Creación de un eslogan.
			elemento = doc.CreateElement("eslogan");
			elemento.InnerText =
				"Vuelos fantásticos. " +
				"La pesadilla de la realidad. " +
				"Ataques terroristas. " +
				"Compras a media noche. " +
				"Amor verdadero. " +
				"Y fontanería creativa.";
 
			doc.SelectSingleNode("/pelicula/esloganes").AppendChild(elemento);
 
			Console.WriteLine(doc.OuterXml);
		}
 
		catch(Exception e)
		{
			Console.WriteLine("Error: '{0}'", e);
		}
 
		Console.Write("Pulse una tecla para continuar...");
		Console.ReadKey(true);
	}
}

Queda como ejercicio para el lector crear el resto de elementos: produccion, guion, reparto, así como todos sus nodos hijos.

Inserción de la cabeceraEditar

Al documento que acabamos de crear le falta aún algún detalle para estar completo. Por ejemplo, la cabecera. La podemos insertar así:

using System;
using System.Xml;
using System.Xml.Schema;
 
class MainClass
{
	public static void Main(string[] args)
	{
		string sRuta = "c:\\xml\\";
		// string sRuta = "/home/andy/xml/";
 
		try
		{
			XmlDocument doc = new XmlDocument();
 
			XmlDeclaration dec;
			dec = doc.CreateXmlDeclaration("1.0", "", "");
			doc.InsertBefore(dec,doc.DocumentElement);
 
			XmlElement elemento;
			elemento = doc.CreateElement("pelicula");
 
			XmlAttribute atr;
			atr = doc.CreateAttribute("titulo");
			atr.Value = "Brazil";
 
			elemento.SetAttributeNode(atr);
 
			doc.AppendChild(elemento);
 
			Console.WriteLine(doc.OuterXml);
		}
 
		catch(Exception e)
		{
			Console.WriteLine("Error: '{0}'", e);
		}
 
		Console.Write("Pulse una tecla para continuar...");
		Console.ReadKey(true);
	}
}

Directivas DOCTYPEEditar

La inserción de directivas DOCTYPE es muy similar a la inserción de cabeceras vista en la sección anterior:

using System;
using System.Xml;
using System.Xml.Schema;
 
class MainClass
{
	public static void Main(string[] args)
	{
		string sRuta = "c:\\xml\\";
		// string sRuta = "/home/andy/xml/";
 
		try
		{
			XmlDocument doc = new XmlDocument();
 
			XmlDeclaration dec;
			dec = doc.CreateXmlDeclaration("1.0", "", "");
			doc.InsertBefore(dec,doc.DocumentElement);
 
			XmlDocumentType doctype;
			doctype = doc.CreateDocumentType("pelicula", null, null, "<!ELEMENT pelicula ANY>");
			doc.AppendChild(doctype);
 
			XmlElement elemento;
			elemento = doc.CreateElement("pelicula");
 
			XmlAttribute atr;
			atr = doc.CreateAttribute("titulo");
			atr.Value = "Brazil";
 
			elemento.SetAttributeNode(atr);
			doc.AppendChild(elemento);
 
			Console.WriteLine(doc.OuterXml);
		}
 
		catch(Exception e)
		{
			Console.WriteLine("Error: '{0}'", e);
		}
 
		Console.Write("Pulse una tecla para continuar...");
		Console.ReadKey(true);
	}
}

Modificación de elementosEditar

Si lo deseas, es posible modificar el contenido de un determinado elemento:

using System;
using System.Xml;
using System.Xml.Schema;
 
class MainClass
{
	public static void Main(string[] args)
	{
		string sRuta = "c:\\xml\\";
		// string sRuta = "/home/andy/xml/";
 
		try
		{
			XmlDocument doc = new XmlDocument();
 
			doc.PreserveWhitespace = true;
			doc.Load(sRuta + "brazil.xml");
 
			XmlNode eslogan;
			eslogan = doc.SelectSingleNode("/pelicula/esloganes/eslogan");
			eslogan.InnerText = "No hay eslogan.";
 
			Console.WriteLine(doc.InnerXml);
		}
 
		catch(Exception e)
		{
			Console.WriteLine("Error: '{0}'", e);
		}
 
		Console.Write("Pulse una tecla para continuar...");
		Console.ReadKey(true);
	}
}

De forma similar, se puede modificar el valor de un atributo:

using System;
using System.Xml;
using System.Xml.Schema;
 
class MainClass
{
	public static void Main(string[] args)
	{
		string sRuta = "c:\\xml\\";
		// string sRuta = "/home/andy/xml/";
 
		try
		{
			XmlDocument doc = new XmlDocument();
 
			doc.PreserveWhitespace = true;
			doc.Load(sRuta + "brazil.xml");
 
			XmlNode pelicula;
			pelicula = doc.SelectSingleNode("/pelicula");
 
			XmlAttributeCollection atrs;
			atrs = pelicula.Attributes;
			atrs["minutos"].Value = "142";
 
			Console.WriteLine(doc.InnerXml);
		}
 
		catch(Exception e)
		{
			Console.WriteLine("Error: '{0}'", e);
		}
 
		Console.Write("Pulse una tecla para continuar...");
		Console.ReadKey(true);
	}
}

Borrado de elementosEditar

Es posible eliminar el elemento esloganes con el siguiente programa:

using System;
using System.Xml;
using System.Xml.Schema;
 
class MainClass
{
	public static void Main(string[] args)
	{
		string sRuta = "c:\\xml\\";
		// string sRuta = "/home/andy/xml/";
 
		try
		{
			XmlDocument doc = new XmlDocument();
 
			doc.PreserveWhitespace = true;
			doc.Load(sRuta + "brazil.xml");
 
			XmlNode nodo;
			nodo = doc.SelectSingleNode("/pelicula/esloganes");
			doc.DocumentElement.RemoveChild(nodo);
 
			Console.Write(doc.OuterXml);
		}
 
		catch(Exception e)
		{
			Console.WriteLine("Error: '{0}'", e);
		}
 
		Console.Write("Pulse una tecla para continuar...");
		Console.ReadKey(true);
	}
}

En lugar de eliminar todos los eslóganes, es posible limitarse a uno de ellos:

using System;
using System.Xml;
using System.Xml.Schema;
 
class MainClass
{
	public static void Main(string[] args)
	{
		string sRuta = "c:\\xml\\";
		// string sRuta = "/home/andy/xml/";
 
		try
		{
			XmlDocument doc = new XmlDocument();
 
			doc.PreserveWhitespace = true;
			doc.Load(sRuta + "brazil.xml");
 
			XmlNode esloganes;
			esloganes = doc.SelectSingleNode("/pelicula/esloganes");
 
			XmlNode eslogan;
			eslogan = doc.SelectSingleNode("/pelicula/esloganes/eslogan");
			esloganes.RemoveChild(eslogan);
 
			Console.Write(doc.OuterXml);
		}
 
		catch(Exception e)
		{
			Console.WriteLine("Error: '{0}'", e);
		}
 
		Console.Write("Pulse una tecla para continuar...");
		Console.ReadKey(true);
	}
}

El borrado también puede limitarse a un atributo:

using System;
using System.Xml;
using System.Xml.Schema;
 
class MainClass
{
	public static void Main(string[] args)
	{
		string sRuta = "c:\\xml\\";
		// string sRuta = "/home/andy/xml/";
 
		try
		{
			XmlDocument doc = new XmlDocument();
 
			doc.PreserveWhitespace = true;
			doc.Load(sRuta + "brazil.xml");
 
			XmlNode nodo;
			nodo = doc.SelectSingleNode("pelicula");
 
			XmlAttributeCollection atrs;
			atrs = nodo.Attributes;
			atrs.Remove(atrs["minutos"]);
 
			Console.Write(doc.OuterXml);
		}
 
		catch(Exception e)
		{
			Console.WriteLine("Error: '{0}'", e);
		}
 
		Console.Write("Pulse una tecla para continuar...");
		Console.ReadKey(true);
	}
}

Almacenamiento del documentoEditar

Cuando terminemos de realizar las operaciones deseadas con el documento XML, podemos guardar los cambios. Añada el siguiente fragmento de código al bloque try, tras las operaciones que haya realizado sobre el documento:

...
XmlTextWriter escriba =
  newXmlTextWriter(sRuta + "brazil2.xml", null);
escriba.Formatting = Formatting.Indented;
doc.Save(escriba);
...
El contenido de la comunidad está disponible bajo CC-BY-SA a menos que se indique lo contrario.