Uma Instância do XSD

Esta seção demonstrará como escrever um XML Schema. Você também aprenderá diferentes métodos para escrever schema.

Documento XML

Vamos ver o documento XML chamado "shiporder.xml":

<?xml version="1.0" encoding="ISO-8859-1"?>
<shiporder orderid="889923">


 <orderperson>George Bush</orderperson>
 <shipto>
  <name>John Adams</name>
  <address>Oxford Street</address>
  <city>London</city>
  <country>UK</country>
 </shipto>
 <item>
  <title>Empire Burlesque</title>
  <note>Special Edition</note>
  <quantity>1</quantity>
  <price>10.90</price>
 </item>
 <item>
  <title>Hide your heart</title>
  <quantity>1</quantity>
  <price>9.90</price>
 </item>
</shiporder>

O documento XML acima inclui o elemento raiz "shiporder", que contém um atributo obrigatório chamado "orderid". O elemento "shiporder" contém três elementos filhos diferentes: "orderperson", "shipto" e "item". O elemento "item" aparece duas vezes, contendo um "title", um elemento opcional "note", um "quantity" e um elemento "price".

Esta linha xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance", informa ao analisador XML que ele deve validar o documento com base em algum schema. Esta linha: xsi:noNamespaceSchemaLocation="shiporder.xsd" define a localização do schema (aqui, ele está no mesmo diretório que "shiporder.xml").

Criar um XML Schema

Agora, precisamos criar um schema para o documento XML acima.

Podemos começar abrindo um novo arquivo e nomeá-lo "shiporder.xsd" . Para criar o schema, precisamos simplesmente seguir a estrutura do documento XML, definindo cada elemento que encontramos. Primeiro, começamos com uma declaração XML padrão:

<?xml version="1.0" encoding="ISO-8859-1" ?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
...
...
</xs:schema>

No schema acima, usamos o espaço de nomes padrão (xs), que está associado ao Schema language definition (definição da linguagem Schema), cujo valor padrão é http://www.w3.org/2001/XMLSchema.

A seguir, precisamos definir o elemento "shiporder" . Este elemento possui um atributo que contém outros elementos, portanto, o consideramos um tipo composto. Os elementos filhos do elemento "shiporder" são cercados pelo elemento xs:sequence , que define a ordem dos elementos:

<xs:element name="shiporder">
 <xs:complexType>
  <xs:sequence>
  ...
  ...
  </xs:sequence>
  ...
 </xs:complexType>
</xs:element>

Em seguida, precisamos definir o elemento "orderperson" como um tipo simples (isso porque ele não contém quaisquer atributos ou outros elementos). O prefixo do tipo (xs:string) é definido pelo prefixo do espaço de nomes, que está associado ao XML schema que indica os tipos de dados schema pré-definidos:

<xs:element name="orderperson" type="xs:string"/>

A seguir, preciso definir dois elementos como tipos compostos: "shipto" e "item" . Vamos começar com a definição do elemento "shipto" :

<xs:element name="shipto">
 <xs:complexType>
  <xs:sequence>
   <xs:element name="name" type="xs:string"/>
   <xs:element name="address" type="xs:string"/>
   <xs:element name="city" type="xs:string"/>
   <xs:element name="country" type="xs:string"/>
  </xs:sequence>
 </xs:complexType>
</xs:element>

Através do schema, podemos usar as propriedades maxOccurs e minOccurs para definir o número de vezes que um elemento pode aparecer. maxOccurs define o número máximo de vezes que um elemento pode aparecer, enquanto minOccurs define o número mínimo de vezes que um elemento pode aparecer. O valor padrão para maxOccurs e minOccurs é 1!

Agora, podemos definir o elemento "item" . Este elemento pode aparecer várias vezes dentro do elemento "shiporder" . Isso é alcançado definindo o valor da propriedade maxOccurs do elemento "item" como "unbounded" , permitindo que o elemento "item" apareça tantas vezes quanto o criador desejar. Note que o elemento "note" é opcional. Já definimos a propriedade minOccurs deste elemento como 0:

<xs:element name="item" maxOccurs="unbounded">
 <xs:complexType>
  <xs:sequence>
   <xs:element name="title" type="xs:string"/>
   <xs:element name="note" type="xs:string" minOccurs="0"/>
   <xs:element name="quantity" type="xs:positiveInteger"/>
   <xs:element name="price" type="xs:decimal"/>
  </xs:sequence>
 </xs:complexType>
</xs:element>

Agora, podemos declarar os atributos do elemento "shiporder". Como este é um atributo obrigatório, definimos use="required".

Notas:A declaração deste atributo deve ser colocada no final:

<xs:attribute name="orderid" type="xs:string" use="required"/>

Este é o índice de documentos do arquivo de schema chamado "shiporder.xsd":

<?xml version="1.0" encoding="ISO-8859-1" ?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="shiporder">
 <xs:complexType>
  <xs:sequence>
   <xs:element name="orderperson" type="xs:string"/>
   <xs:element name="shipto">
    <xs:complexType>
     <xs:sequence>
      <xs:element name="name" type="xs:string"/>
      <xs:element name="address" type="xs:string"/>
      <xs:element name="city" type="xs:string"/>
      <xs:element name="country" type="xs:string"/>
     </xs:sequence>
    </xs:complexType>
   </xs:element>
   <xs:element name="item" maxOccurs="unbounded">
    <xs:complexType>
     <xs:sequence>
      <xs:element name="title" type="xs:string"/>
      <xs:element name="note" type="xs:string" minOccurs="0"/>
      <xs:element name="quantity" type="xs:positiveInteger"/>
      <xs:element name="price" type="xs:decimal"/>
     </xs:sequence>
    </xs:complexType>
   </xs:element>
  </xs:sequence>
  <xs:attribute name="orderid" type="xs:string" use="required"/>
 </xs:complexType>
</xs:element>
</xs:schema>

Dividir Schema

O método de design anterior é muito fácil, mas torna-se difícil de ler e manter quando o documento é complexo.

O método de design a seguir é baseado em definir primeiro todos os elementos e atributos, e então usar o atributo ref para referenciá-los.

Este é o arquivo de schema projetado com um novo método:

<?xml version="1.0" encoding="ISO-8859-1" ?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<!-- Definição do elemento simples -->
<xs:element name="orderperson" type="xs:string"/>
<xs:element name="name" type="xs:string"/>
<xs:element name="address" type="xs:string"/>
<xs:element name="city" type="xs:string"/>
<xs:element name="country" type="xs:string"/>
<xs:element name="title" type="xs:string"/>
<xs:element name="note" type="xs:string"/>
<xs:element name="quantity" type="xs:positiveInteger"/>
<xs:element name="price" type="xs:decimal"/>
<!-- Definição do atributo -->
<xs:attribute name="orderid" type="xs:string"/>
<!-- Definição do elemento composto -->
<xs:element name="shipto">
 <xs:complexType>
  <xs:sequence>
   <xs:element ref="name"/>
   <xs:element ref="address"/>
   <xs:element ref="city"/>
   <xs:element ref="country"/>
  </xs:sequence>
 </xs:complexType>
</xs:element>
<xs:element name="item">
 <xs:complexType>
  <xs:sequence>
   <xs:element ref="title"/>
   <xs:element ref="note" minOccurs="0"/>
   <xs:element ref="quantity"/>
   <xs:element ref="price"/>
  </xs:sequence>
 </xs:complexType>
</xs:element>
<xs:element name="shiporder">
 <xs:complexType>
  <xs:sequence>
   <xs:element ref="orderperson"/>
   <xs:element ref="shipto"/>
   <xs:element ref="item" maxOccurs="unbounded"/>
  </xs:sequence>
  <xs:attribute ref="orderid" use="required"/>
 </xs:complexType>
</xs:element>
</xs:schema>

Uso de tipos nomeados

O terceiro método de design define classes ou tipos, permitindo-nos reutilizar definições de elementos. A maneira específica é: primeiramente nomear elementos simples e compostos, e então apontar para eles através da propriedade type do elemento.

Este é um arquivo de schema projetado usando o terceiro método ("shiporder.xsd"):

<?xml version="1.0" encoding="ISO-8859-1" ?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:simpleType name="stringtype">
 <xs:restriction base="xs:string"/>
</xs:simpleType>
<xs:simpleType name="inttype">
 <xs:restriction base="xs:positiveInteger"/>
</xs:simpleType>
<xs:simpleType name="dectype">
 <xs:restriction base="xs:decimal"/>
</xs:simpleType>
<xs:simpleType name="orderidtype">
 <xs:restriction base="xs:string">
  <xs:pattern value="[0-9]{6}"/>
 </xs:restriction>
</xs:simpleType>
<xs:complexType name="shiptotype">
 <xs:sequence>
  <xs:element name="name" type="stringtype"/>
  <xs:element name="address" type="stringtype"/>
  <xs:element name="city" type="stringtype"/>
  <xs:element name="country" type="stringtype"/>
 </xs:sequence>
</xs:complexType>
<xs:complexType name="itemtype">
 <xs:sequence>
  <xs:element name="title" type="stringtype"/>
  <xs:element name="note" type="stringtype" minOccurs="0"/>
  <xs:element name="quantity" type="inttype"/>
  <xs:element name="price" type="dectype"/>
 </xs:sequence>
</xs:complexType>
<xs:complexType name="shipordertype">
 <xs:sequence>
  <xs:element name="orderperson" type="stringtype"/>
  <xs:element name="shipto" type="shiptotype"/>
  <xs:element name="item" maxOccurs="unbounded" type="itemtype"/>
 </xs:sequence>
 <xs:attribute name="orderid" type="orderidtype" use="required"/>
</xs:complexType>
<xs:element name="shiporder" type="shipordertype"/>
</xs:schema>

O elemento de restrição mostra que o tipo de dados é derivado do tipo de dados da namespace W3C XML Schema. Portanto, o seguinte fragmento significa que o valor do elemento ou atributo deve ser do tipo string:

<xs:restriction base="xs:string">

O elemento de restrição é frequentemente usado para aplicar restrições a elementos. Veja os seguintes fragmentos acima do schema:

<xs:simpleType name="orderidtype">
 <xs:restriction base="xs:string">
  <xs:pattern value="[0-9]{6}"/>
 </xs:restriction>
</xs:simpleType>

Este código indica que o valor do elemento ou atributo deve ser uma string e deve ser contínua de seis caracteres, e esses caracteres devem ser números de 0 a 9.