Buscar este blog

miércoles, 30 de marzo de 2011

Validando esquemas xml con .Net Framework

Uno de los objetivos de los esquemas xml (archivos .xsd) es poder validar que un archivo xml cumpla con las reglas que se especifican en el esquema, .Net tiene el API necesaria para realizar esta validación y es muy sencillo.
Consideremos el siguiente esquema:

   1:  <?xml version="1.0" standalone="yes"?>
   2:  <xs:schema id="Peliculas"
   3:                       targetNamespace="ProbadorConsola"
   4:                       xmlns:xs="http://www.w3.org/2001/XMLSchema"
   5:                       xmlns="ProbadorConsola"
   6:                       elementFormDefault="qualified">
   7:    <xs:element name="Peliculas">
   8:      <xs:complexType>
   9:        <xs:choice minOccurs="0" maxOccurs="unbounded">
  10:          <xs:element name="Pelicula">
  11:            <xs:complexType>
  12:              <xs:sequence>
  13:                <xs:element name="Titulo" type="xs:string" minOccurs="0" />
  14:                <xs:element name="Director" type="xs:string" minOccurs="0" />
  15:                <xs:element name="Estrenado" type="xs:string" minOccurs="0" />
  16:                <xs:element name="Actores" minOccurs="0" maxOccurs="unbounded">
  17:                  <xs:complexType>
  18:                    <xs:sequence>
  19:                      <xs:element name="Actor" minOccurs="0" maxOccurs="unbounded">
  20:                        <xs:complexType>
  21:                          <xs:sequence>
  22:                            <xs:element name="Nombre" type="xs:string" minOccurs="0" />
  23:                            <xs:element name="Nacimiento" type="xs:string" minOccurs="0" />
  24:                            <xs:element name="Roles" minOccurs="0" maxOccurs="unbounded">
  25:                              <xs:complexType>
  26:                                <xs:sequence>
  27:                                  <xs:element name="Rol" minOccurs="0" maxOccurs="unbounded">
  28:                                    <xs:complexType>
  29:                                      <xs:sequence>
  30:                                        <xs:element name="NombrePelicula" type="xs:string" minOccurs="0" />
  31:                                        <xs:element name="NombreRol" type="xs:string" minOccurs="0" />
  32:                                      </xs:sequence>
  33:                                    </xs:complexType>
  34:                                  </xs:element>
  35:                                </xs:sequence>
  36:                              </xs:complexType>
  37:                            </xs:element>
  38:                          </xs:sequence>
  39:                        </xs:complexType>
  40:                      </xs:element>
  41:                    </xs:sequence>
  42:                  </xs:complexType>
  43:                </xs:element>
  44:              </xs:sequence>
  45:            </xs:complexType>
  46:          </xs:element>
  47:        </xs:choice>
  48:      </xs:complexType>
  49:    </xs:element>
  50:  </xs:schema>

Y el contenido xml que queremos validar:

   1:  <Peliculas xmlns="ProbadorConsola">
   2:      <Pelicula>
   3:      <Titulo>Mazinger</Titulo>
   4:      <Director>Jackie Chan</Director>
   5:      <Estrenado>1975-03-19T00:00:00</Estrenado>
   6:      <Actores>
   7:        <Actor>
   8:          <Nombre>John Wayne</Nombre>
   9:          <Nacimiento>1915-10-23T00:00:00</Nacimiento>
  10:          <Roles>
  11:            <Rol>
  12:              <NombrePelicula>Mazinger</NombrePelicula>
  13:              <NombreRol>Estrella</NombreRol>
  14:            </Rol>
  15:          </Roles>
  16:        </Actor>
  17:      </Actores>
  18:    </Pelicula>
  19:  </Peliculas>

Lo primero que debemos hacer es validar que el documento contenga el espacio de nombres del esquema si no lo contiene la validación fallara diciéndonos que el documento es valido aun cuando en realidad no cumpla las reglas del esquema.
El código para encontrar el espacio de nombres (c#):

   1:  XDocument peliculas = XDocument.Load("peliculas.xml");
   2:  XPathNavigator nav = peliculas.CreateNavigator();
   3:  nav.MoveToFollowing(XPathNodeType.Element);
   4:  IDictionary<string, string> ns
   5:      = nav.GetNamespacesInScope(XmlNamespaceScope.All);
   6:  bool schemaFound = false;
   7:  foreach(KeyValuePair<string, string> namespaces in ns) {
   8:      if(namespaces.Value.CompareTo("ProbadorConsola") == 0)
   9:          schemaFound = true;
  10:  }
  11:  if(!schemaFound) {
  12:      Console.WriteLine("Esquema no encontrado");
  13:      return;
  14:  }
Ahora si podemos proceder a validar el documento con el esquema que puede estar en un archivo local o en Internet:

   1:  XmlSchemaSet schema = new XmlSchemaSet();
   2:  schema.Add("ProbadorConsola", "peliculas.xsd");
   3:  peliculas.Validate(schema, null);
   4:  Console.WriteLine("Esquema valido");
   5:  Console.ReadLine();

Hacemos notar que si utilizas Linq a XSD todo esto lo hace en una sola linea de código al cargar el documento.

Para aprender más sobre el uso de XML en .Net Framework visita:
Lista de artículos acerca del uso de XML en .Net Framework

No hay comentarios:

Publicar un comentario