sexta-feira, 9 de março de 2012

XML SCHEMA - PARTE VI Exemplo

Um exemplo

Este capítulo vai demostrar como escrever um XML Schema. Você também aprenderá que um esquema pode ser escrito de diferentes maneiras.

Um documento XML

Vamos dar uma olhada nesse documento XML chamado "shiporder.xml":
  
  <?xml version="1.0" encoding="ISO-8859-1"?>
  
  <shiporder orderid="889923"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:noNamespaceSchemaLocation="shiporder.xsd">
  <orderperson>John Smith</orderperson>
  <shipto>
   <name>Ola Nordmann</name>
   <address>Langgt 23</address>
   <city>4000 Stavanger</city>
   <country>Norway</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 consiste de um 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 e contém um elemento "title", um elemento opcional "note", um elemento "quantity" e um "price".
A linha acima: xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" diz ao parser XML que o documento deve ser válidado por um esquema. A linha: xsi:noNamespaceSchemaLocation="shiporder.xsd" especifica ONDE o esquema reside (no caso, ele está no mesmo diretório que "shiporder.xml").

Crie um XML Schema

Agora nós vamos criar um esquema para o documento XML acima!
Nós começamos abrindo um novo arquivo que chamaremos "shiporder.xsd". Para criar o esquema nós podemos simplesmente seguir a estrutura no documento XML e definir cada elemento a medida que o encontramos. Nós vamos começar com a declaração XML padrão, seguida do elemento xs:schema que define um esquema:
  
  <?xml version="1.0" encoding="ISO-8859-1" ?>
  <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
  
  ...
  
  ...
  
  </xs:schema>
No esquema acima nós usamos o namespace padrão (xs), e a URI associada com este namespace na linguagem de definição Schema, que tem o valor padrão http://www.w3.org/2001/XMLSchema.
Em seguida, nós temos que definir o elemento "shiporder". Este elemento tem um atributo e contém outros elemento, assim o consideramos um tipo complexo. Os elementos filhos de "shiporder" são englobados por um elemento xs:sequence que define uma ordem para eles:
  
  <xs:element name="shiporder">
     <xs:complexType>
         <xs:sequence>
         ...
         ...
         </xs:sequence>
     </xs:complexType>
  </xs:element>
Então nós temos que definir o elemento "orderperson" como um tipo simples (porque ele não contém nenhum atributo ou elemento). O tipo (xs:string) é prefixado com o prefixo do namespace associado ao XML Schema que indica um tipo de dado pré-definido:
  <xs:element name="orderperson" type="xs:string"/>
Em seguida, nós temos que definir dois elementos que são do tipo complexo: "shipto" e "item". Nós começamos definindo o 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>
Com esquemas nós podemos definir o número possível de ocorrências de um elemento com os atributos maxOccurs e minOccurs. maxOccurs especifica o número máximo de ocorrências para um elemento e minOccurs o número mínimo. O valor padrão para maxOccurs e minOccurs é 1!!!
Agora nós podemos definir o elemento "item". Este elemento pode aparecer muitas vezes dentro do elemento "shiporder". Isto é especificado definindo o atributo maxOccurs do elemento "item" para "unbounded" que significa que podem haver tantas ocorrências do elemento "item" quanto o autor desejar. Note que o elemento "note" é opcional. Nós especificamos isto definindo o atributo minOccurs em zero:
  
  <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 nós podemos declarar o atributo do elemento "shiporder". Como ele é um atributo obrigatório nós especificamos use="required".
Nota: As declaraçõs de atributos sempre devem vir no final:
  <xs:attribute name="orderid" type="xs:string" use="required"/>
Aqui está a listagem completa do arquivo 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>

Divida o schema

O método de design anterior é muito simples, mas pode ser muito difícil de ler e manter quando os documentos são complexos!
O próximo método de design é baseado na definição de todos os elementos e atributos primeiro, e então referenciá-los usando o atributo ref.
Aqui está a nova aparência o arquivo de esquema ("shiporder.xsd"):
  
  <?xml version="1.0" encoding="ISO-8859-1"?>
  <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
  
  <!-- definição de elementos 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 de atributos -->
  <xs:attribute name="orderide" type="xs:string"/>
  
  <!-- definição de elementos complexos -->
  <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>

Usando tipos nomeados

O terceiro método de design define classes e tipos, que nos permite reutilizar a definição de elementos. Isto é feito nomeando os elementos simpleTypes e complexTypes, e então apontando para eles com o atributo type do elemento.
Aqui está a nova forma do arquivo de esquema ("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:restricion>
  </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"/>
         <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 restriction indica que o tipo de dado é derivado de um namespace de XML Schema do W3C. Assim, esse fragmento:
  <xs:restriction base="xs:string"/>
significa que o valor do elemento ou atributo de ser uma string.
O elemento restriction costuma ser mais usado para aplicar restrições nos elementos. Observe as seguintes linhas do esquema acima:
  
  <xs:simpleType name="orderidtype">
     <xs:restriction base="xs:string">
         <xs:pattern value="[0-9]{6}"/>
     </xs:restriction>
  </xs:simpleType>
Isto indica que o valor do elemento ou atributo deve ser uma string e deve exatamente seis caracteres e cada caracter deve ser um número entre 0 e 9.

Nenhum comentário:

Postar um comentário