Validación e Tipos de Documentos

De Wiki do Ciclo ASIR do IES de Rodeira

Índice

Introducción a Validación de Documentos.

A validación XML consiste na comprobación de que un documento XML está ben formado e se axusta a unha estructura previamente definida (esquema). Para que un documento XML esté ben formado debe seguir as regras básicas establecidas para o deseño de documentos XML. A validez dun documento XML require que, además de estar ben formado, a súa estructura se axuste á definición do documento establecida previamente mediante unha definición de tipo de documento.

Boxinfo info.png
A validación dun documento garantiza que sigue o estándar establecido e que polo tanto pode ser procesado por software realizado seguindo ese estándar.

Para a definición dos documentos utilízanse varias linguaxes de definición de estructuras de datos, sendo o máis empregado hoxe en día o DTD (Document Type Definition) convivindo con outras máis complexas como XML-Schema, Relax NG ou Schematron.

Definición de Tipos de Documentos

DTD

Unha Definición de Tipo de Documento é unha descripción da estructura e sintaxe dun documento XML ou SGML. A súa función básica é a descripción do formato dos datos de modo que se manteña a consistencia entre todos os documentos válidos que utilizan o mesmo DTD. O DTD pódese incluir dentro do arquivo do documento, pero normalmente se almacena nun ficheiro de texto separado, e indica a sintaxis a seguir por un documento XML como por exemplo XHTML.

Nun DTD se describe:

Elementos
Que etiquetas se permiten e que contido poden ter.
Estructura
Describe en que orde deber ir as etiquetas no documento.
Anidamento
Describe que etiquetas van dentro de outras.

Si declaramos o DTD dentro do ficheiro XML, debería estar dentro dunha definición DOCTYPE coa seguinte sintaxe:

  <!DOCTYPE root-element [element-declarations]>

Por exemplo:

<?xml version="1.0"?>
<!DOCTYPE note [
<!ELEMENT note (to,from,heading,body)>
<!ELEMENT to (#PCDATA)>
<!ELEMENT from (#PCDATA)>
<!ELEMENT heading (#PCDATA)>
<!ELEMENT body (#PCDATA)>
]>
<note>
<to>Tove</to>
<from>Jani</from>
<heading>Reminder</heading>
<body>Don't forget me this weekend</body>
</note>

Si o DTD está declarado nun ficheiro externo, se pode declarar coa seguinte sintaxe:

  <!DOCTYPE root-element SYSTEM "filename">

Por exemplo, o caso anterior quedaría como sigue:

  • Ficheiro “nota.dtd”
<!ELEMENT note (to,from,heading,body)>
<!ELEMENT to (#PCDATA)>
<!ELEMENT from (#PCDATA)>
<!ELEMENT heading (#PCDATA)>
<!ELEMENT body (#PCDATA)>
  • Ficheiro “nota.xml”
<?xml version="1.0"?>
<!DOCTYPE note SYSTEM "note.dtd">
<note>
	<to>Tove</to>
	<from>Jani</from>
	<heading>Reminder</heading>
	<body>Don't forget me this weekend!</body>
</note>

A sintaxe xeral da declaración DOCTYPE é a seguinte:

 <!DOCTYPE  [Raiz]  [Dispoñibilidade]  "[Rexistro]// [Organización]// [Tipo]  [Etiqueta]// [Linguaxe]"    "[URL]">
 "//" se utiliza como separación entre os distintos campos.
[Raíz]
– Indica o nome da etiqueta raíz declarada no DTD. Por exemplo <html> en HTML.
[Dispoñibilidade]
– Indica si e un obxecto accesible públicamente (PUBLIC) ou un recurso do sistema (SYSTEM) como unha URL ou un ficheiro local.
[Rexistro]
– Pode ser “+” indicando que a organización que se indica a continuación forma parte da ISO, ou “-”, indicando que non. O IETF e W3C non forman parte da ISO e polo tanto utilizan “-”.
[Organization]
– E unha etiqueta única indicando a organización responsable da creación e mantemento do DTD.
[Tipo]
– E o tipo de obxecto que está a ser referenciado, no caso dos DTD, se especificará DTD.
[Etiqueta]
– E unha descripción pública única do DTD que está a ser referenciado.
[Linguaxe]
– E a linguaxe que se utilizará na creación do documento. Se debe especificar o código da linguaxe segun o estándar ISO 639 (dúas letras maiúsculas)
[URL]
– URL ao DTD ao que se está a facer referencia

Para a creación dun DTD distinguiremos entre:

Elementos
Son as etiquetas que formarán o documento XML.
Atributos
Proporcionan información extra sobre un elemento, no XML irán situados no interior da declaración de apertura da etiqueta.
Entidades
Definición de abreviaturas para referirse a caracteres de uso especial en XML, como por exemplo   en XHTML.
PCDATA
E o texto que se atopa dentro dunha etiqueta XML. Este texto o examina o analizador XML en busca de entidades e novos elementos anidados.
CDATA
E o texto que se atopa dentro dunha etiqueta XML. Este texto NON será examinado en busca de novos elementos anidados e entidades.

As DTD teñen limitacións como a falta de definición de etiquetas locais a outros elementos, de modo que non se permite repetir etiquetas aínda que estean en ámbitos distintos (por exemplo, <delegado> dentro da etiqueta <clase> e <delegado> dentro da etiqueta <consello escolar>) forzando o uso de espacios de nomes. Tampouco é posible indicar con precisión os tipos de datos dos atributos dos elementos... etc. Para superar estas limitacións apareceron outras linguaxes de esquema como XML-Schema.

XML-Schema

Como xa comentamos, XML-Schema permite unha definición máis estricta dos documentos XML, permitíndonos indicar entre outras cousas a información permitida no mesmo. Un resumo útil para a elaboración de documentos XML-Schema pode ser o seguinte:

  • Referencia a un XML-Schema nun documento XML

Os documentos XML referencian o seu Schema mediante atributos situados na etiqueta raíz do documento. Un exemplo sería o seguinte:

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

Alternativamente, dun xeito máis simple:

<etiqueta_raiz  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
		    xsi:noNamespaceSchemaLocation="nososchema.xsd">
......
</etiqueta_raiz>
  • Encabezado dun documento XML-Schema

A definición dun documento XML-Schema comenza cunha etiqueta schema, que pode levar diversos atributos (consultar manual). Un xeito de comenzar un documento XML-Schema sería o seguinte:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://urldonososchema"
           xmlns="http://urldonososchema" elementFormDefault="qualified">

Alternativamente, dun xeito máis simple:

<?xml version="1.0" encoding="UTF-8" ?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
...
</xs:schema>
  • Definición de etiquetas (elements)

As etiquetas (chamadas elements en XML-Schema) poden ser simples ou complexas. As etiquetas simples son aquelas que únicamente teñen información como contido, e non conteñen nin outras etiquetas nin atributos (un atributo é unha característica da etiqueta que se indica dentro da propia etiqueta, por exemplo en <documento linguaxe=”galego”>, linguaxe sería un atributo da etiqueta documento, sendo polo tanto unha etiqueta complexa.

As etiquetas (elements) simples declaranse do seguinte xeito:

<xs:element name="xxx" type="yyy"/>

Donde name é o nome da etiqueta e type o seu tipo (o tipo de información que pode conter a etiqueta). XML-Schema dispón de varios tipos predefinidos que podes consultar no manual. Ás etiquetas simples se lles pode asignar un valor por defecto:

<xs:element name="xxx" type="yyy" default=”valor por defecto”/>

Ou un valor fixo:

<xs:element name="xxx" type="yyy" fixed=”valor fixo”/>

A definición de etiquetas complexas é similar a das etiquetas simples, pero no interior da súa definición se indicarán os distintos elementos que a compoñen:

<xs:element name=”etiqueta”>
	<xs:complexType>
		Definición das etiquetas e atributos que poden ir na etiqueta
	</xs:complexType>
</xs:element>

XML-Schema dispon de varios tipos de datos, sendo os máis habituais os seguintes: xs:string, xs:decimal, xs:integer, xs:boolean, xs:date, xs:time

  • Definición de atributos (attributes)

Como xa comentamos, os atributos son características dunha etiqueta que se indican dentro da propia etiqueta. A súa definición é como sigue:

<xs:attribute name="xxx" type="yyy"/>

Do mesmo xeito que as etiquetas simples é posible indicar un valor fixo, ou una valor por defecto, pero tamén podemos indicar si queremos que sexa obrigatorio especificar o atributo mediante a seguinte declaración:

<xs:attribute name="lang" type="xs:string" use="required"/>
  • Restriccións de valores

En XML-Schema podemos restrinxir a información que se pode especificar no interior de unha etiqueta ou dun atributo mediante os tipos de datos, pero aínda se pode restrinxir máis o conxunto de valores permitidos especificando restriccións sobre cada tipo:

<xs:element name=”elemento”>
  <xs:simpleType>
    <xs:restriction base=”xs:tipo_base”>
	Definición da restricción
    </xs:restriction>
  </xs:simpleType>
</xs:element>

A definición das restriccións pode ser de varios tipos, como valores máximos e/ou mínimos, enumeracións, patróns de validación (pattern), lonxitude.... etc. (consultar manual). Vexamos un par de exemplos:

1.- o contido da etiqueta dni ten que consistir en 7 díxitos numéricos seguidos dunha letra maiúscula.

<xs:element name=”dni”>
	<xs:simpleType>
		<xs:restriction base=”xs:string”>
			<xs:pattern value=”[0-9][0-9][0-9][0-9][0-9][0-9][0-9][A-Z]/>
		</xs:restriction>
	</xs:simpleType>
</xs:element>

2.- o contido da etiqueta texto ten que ter como mínimo 8 letras, e como máximo 30

<xs:element name=”texto”>
	<xs:simpleType>
		<xs:restriction base=”xs:string”>
			<xs:minLength value="8"/>
			<xs:maxLength value=”30”/>
		</xs:restriction>
	</xs:simpleType>
</xs:element>

Outros tipos de restriccións que se poden especificar son:

  • enumeration - Define unha lista de valores aceptables:
<xs:enumeration value="Audi"/>
<xs:enumeration value="Golf"/>
<xs:enumeration value="BMW"/>
  • fractionDigits - Número máximo de posicións decimais a utilizar. (a base debe ser xs:decimal)
  • length - Número exacto de caracteres ou de elementos de lista
  • maxExclusive - Valor máximo dun contido numérico (non incluído)
  • maxInclusive - Valor máximo dun contido numérico (incluído)
  • maxLength - Lonxitude máxima dun contido
  • minExclusive - Valor mínimo dun contido numérico (non incluido)
  • minInclusive - Valor mínimo dun contido numérico (incluido)
  • minLength - O contido debe ter máis que o número de caracteres especificado
  • pattern - Especifica un patron que debe cumplir o contido
  • totalDigits - Número máximo de díxitos permitido
  • whiteSpace - Uso dos espacios en blanco no documento. Pode ser “preserve”, “replace” ou “collapse”
  • Definición do contido das etiquetas complexas

Unha etiqueta complexa pode conter:

- nada (únicamente ten atributos, non contido): Nese caso nos limitamos a declarar os atributos dentro da declaración de complexType:
	<product prodid='9'/>
	<xs:element name="product">
		<xs:complexType>
			<xs:attribute name="prodid" type="xs:positiveInteger"/>
		</xs:complexType>
	</xs:element>
- so outros elementos: Podemos definir os elementos como:
1. SEQUENCE: Unha secuencia: Os elementos declarados deben aparecer no orde indicado:
		<person><firstname>Manuel</firstname><lastname>Pérez</lastname></person>
	<xs:element name="person">  
		<xs:complexType>
			<xs:sequence>
				<xs:element name="firstname" type="xs:string"/>
				<xs:element name="lastname" type="xs:string"/>
			</xs:sequence>
		</xs:complexType>
	</xs:element>
2. CHOICE: Unha etiqueta a elexir entre un grupo (choice)
	<contacto><email>correo@dominio.es</email></contacto>
	<xs:element name="contacto">  
		<xs:complexType>
			<xs:choice>
				<xs:element name="telefono" type="xs:string"/>
				<xs:element name="email" type="xs:string"/>
			</xs:choice>
		</xs:complexType>
	</xs:element>
3. ALL: Varias etiquetas que poden aparecer en calqueira orden
  <person><lastname>Pérez</lastname><firstname>Manuel</firstname></person>
	<xs:element name="person">  
		<xs:complexType>
			<xs:all>
				<xs:element name="firstname" type="xs:string"/>
				<xs:element name="lastname" type="xs:string"/>
			</xs:all>
		</xs:complexType>
	</xs:element>
- so texto (e atributos): Etiquetas con atributos e so con texto no seu interior. Se define un contido simple dentro do contido complexo, extendendo un tipo ou poñendo unha restricción:
	<shoesize country="france">35</shoesize>
	<xs:element name="shoesize">
		<xs:complexType>
			<xs:simpleContent>
				<xs:extension base="xs:integer">
					<xs:attribute name="country" type="xs:string" />
				</xs:extension>
			</xs:simpleContent>
		</xs:complexType>
	</xs:element>
- contido mixto (outros elementos e texto): Se realiza poñendo mixed=”true” na definición do tipo complexo. Se queremos que unha etiqueta poda aparecer máis dunha vez, podemos especificar o número máximo con maxOccurs na definición da mesma. Do mesmo xeito podemos facer que apareza un número mínimo de veces con minOccurs, pudendo indicar 0 si queremos que poda non aparecer.

Relax NG.

RELAX NG é unha linguaxe de definición de esquemas para XML, basado en XML. Consideremos un documento XML que representa información sobre libros dunha biblioteca:

<biblioteca>
	<libro>
		<titulo>20000 Leguas de viaxe submarina</titulo>
		<autor>Julio Verne</autor>
	</libro>
	<libro>
		<titulo>Festín de Corvos</titulo>
		<autor>R.R. Martin</autor>
	</libro>
</biblioteca>

A definición do esquema DTD seria:

<!DOCTYPE biblioteca [
<!ELEMENT biblioteca (libro*)>
<!ELEMENT libro (titulo, autor)>
<!ELEMENT titulo (#PCDATA)>
<!ELEMENT autor (#PCDATA)>
]>

E o Relax NG sería algo así:

<element name="biblioteca" xmlns="http://relaxng.org/ns/structure/1.0">
  <zeroOrMore>
    <element name="libro">
      <element name="titulo">
        <text/>
      </element>
      <element name="autor">
        <text/>
      </element>
    </element>
  </zeroOrMore>
</element>

Podemos observar etiquetas como <ZeroOrMore> que indican a cardinalidade do contido, pudendo utilizarse por exemplo <OneOrMore>. Examinaremos as etiquetas máis importantes:

<element name="nome"> 	Permite a definición de etiquetas que poden estar presentes no documento XML
<choice> Permite a elección entre dous conxuntos de etiquetas que poden estar agrupados co tag <group>, 
         sería o equivalente ao paréntesis no DTD, e choice faría a función de |. 
         Esta etiqueta utilízase tanto nos elementos como nos atributos, e se poden facer eleccións entre elementos e atributos.
<attribute name="nome"> Vai dentro dun <element> e permite definir atributos do elemento
<optional> Os elementos e atributos definidos dentro dun tag <optional> serán opcionais
<text/>  Indica que o contido do elemento ou atributo é texto. É o valor por defecto para os atributos. 
         Os elementos teñen que ter definido un tipo de contido obrigatoriamente.
<empty/>  Indica que un elemento non ten contido.
<grammar> Grammar permite definir un esquema Relax NG dun xeito "modular", o que simplifica a definición, 
          comprensión e mantemento do mesmo. A etiqueta <grammar> consta dunha etiqueta <start> e de 
          cero ou máis etiquetas <define name='nome'>. Na etiqueta <start> se realizará a definición da etiqueta raíz, 
          cos elementos do segundo nivel facendo referencia á sección <define> onde se atopa o esquema a aplicar, 
          mediante un tag <ref name='nome'>, permitíndose referencias recursivas.
<data type='tipo' [datatypeLibrary='url']/> Esta etiqueta permite definir o tipo de datos da información. 
          O atributo datatypeLibrary contén unha url identificando a librería de tipos de datos a utilizar, 
          sendo  a  de W3C (W3C XML Schema Datatypes)  http://www.w3.org/2001/XMLSchema-datatypes, que define tipos como 
          integer ou double. O atributo datatypeLibrary pode indicarse no tag <data> ou no tag <element> pai.
          Os <data> poden ter parámetros que restrinxen o rango de valores permitidos. Estes parámetros se indican cun 
          elemento fillo <param name='restricción'>, donde restricción pode ser por exemplo maxLength.
	  O tag <define> pode levar un atributo combine que pode ter dous valores distintos:
<choice> - Indica que no documento XML é posible elexir entre todas as definicións co mesmo nome.
<interleave> - Indica que se poden utilizar calqueira dos elementos definidos co mesmo nome, e en calqueira orde.
<value> - Permite indicar un valor fixo para un elemento ou atributo.
<list> - Permite que un elemento ou atributo conteña unha lista de datos.
<interleave> - Permite que os elementos definidos podan especificarse en calqueira orde
<externalRef href='url'> - Permite facer referencia a un esquema RelaxNG definido en outro ficheiro. 
                           Utilízase na separación modular de esquemas mediante o tag <grammar>.