Este capítulo irá demonstrar como escrever um esquema XML. Você também vai aprender que um esquema pode ser escrito de maneiras diferentes.
Um documento XML
Vamos dar uma olhada neste documento XML chamado "shiporder.xml" :
<?xml version="1.0" encoding="UTF-8"?>
<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 é constituído por um elemento raiz, "shiporder" , que contém um atributo necessário chamado "orderid" . O "shiporder" elemento contém três diferentes elementos filho: "orderperson" , "shipto" e "item" . O "item" elemento aparece duas vezes, e ele contém um "title" , um opcional "note" elemento, a "quantity" e um "price" elemento.
A linha acima: xmlns: xsi = "http://www.w3.org/2001/XMLSchema-instance" diz ao analisador XML que este documento devem ser validados contra um esquema. A linha: xsi: noNamespaceSchemaLocation = "shiporder.xsd" especifica onde reside o esquema (here it is in the same folder as "shiporder.xml") .
Criar um esquema XML
Agora queremos criar um esquema para o documento XML acima.
Nós começar por abrir um novo arquivo que chamaremos "shiporder.xsd" . Para criar o esquema que poderia simplesmente seguir a estrutura do documento XML e definir cada elemento como nós encontrá-lo. Vamos começar com a declaração XML padrão seguido pela xs: element esquema que define um esquema:
<?xml version="1.0" encoding="UTF-8" ?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
...
</xs:schema>
No esquema acima usamos o namespace padrão (xs) , eo URI associado a este espaço de nomes é a definição da linguagem Schema, que tem o valor padrão de http://www.w3.org/2001/XMLSchema.
Em seguida, temos de definir o "shiporder" elemento. Este elemento tem um atributo e que contém outros elementos, portanto, considerá-lo como um tipo complexo. Os elementos filho do "shiporder" elemento é rodeado por um xs: elemento de sequência que define uma sequência ordenada de sub elementos:
<xs:element name="shiporder">
<xs:complexType>
<xs:sequence>
...
</xs:sequence>
</xs:complexType>
</xs:element>
Então nós temos que definir o "orderperson" elemento como um tipo simples (porque ele não contém quaisquer atributos ou outros elementos). O tipo (xs:string) é prefixado com o prefixo de namespace associado ao esquema XML que indica um tipo de dados de esquema pré-definido:
<xs:element name="orderperson" type="xs:string"/>
Em seguida, temos que definir dois elementos que são do tipo complexo: "shipto" e "item" . Começamos por definir o "shipto" elemento:
<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 podemos definir o número de possíveis ocorrências de um elemento com os maxOccurs e minOccurs atributos. maxoccurs especifica o número máximo de ocorrências de um elemento e minOccurs especifica o número mínimo de ocorrências de um elemento. O valor padrão para ambos os maxOccurs e minOccurs é 1!
Agora podemos definir o "item" elemento. Este elemento pode aparecer várias vezes dentro de um "shiporder" elemento. Isso é especificado definindo o maxOccurs atributo do "item" elemento a "unbounded" , o que significa que não pode haver tantas ocorrências do "item" elemento como o autor desejar. Observe que a "note" elemento é opcional. Nós especificamos isso definindo os minOccurs atributo para 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>
Nós agora podemos declarar o atributo do "shiporder" elemento. Como este é um atributo necessário que especificar use = "required".
Note: As declarações de atributo devem sempre vir por último:
<xs:attribute name="orderid" type="xs:string" use="required"/>
Aqui está a lista completa do arquivo de esquema chamado "shiporder.xsd" :
<?xml version="1.0" encoding="UTF-8" ?>
<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 esquema
O método de concepção anterior é muito simples, mas pode ser difícil de ler e manter quando os documentos são complexas.
O método de concepção próxima é baseada na definição de todos os elementos e atributos primeiro, e depois se referindo a eles usando o ref atributo.
Aqui está o novo design do arquivo de esquema ("shiporder.xsd") :
<?xml version="1.0" encoding="UTF-8" ?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<!-- definition of simple elements -->
<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"/>
<!-- definition of attributes -->
<xs:attribute name="orderid" type="xs:string"/>
<!-- definition of complex elements -->
<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 projeto define classes ou tipos, que nos permite reutilizar definições de elementos. Isso é feito por nomear os elementos simpleTypes e complexTypes e aponte a eles através do type atributo do elemento.
Aqui é o terceiro projeto do arquivo de esquema ("shiporder.xsd") :
<?xml version="1.0" encoding="UTF-8" ?>
<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 indica que o tipo de dados é derivado de um namespace tipo de dados W3C XML Schema. Assim, o seguinte fragmento significa que o valor do elemento ou atributo deve ser um valor de sequência:
<xs:restriction base="xs:string">
O elemento de restrição é mais frequentemente usado para aplicar restrições aos elementos. Olhe para 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>
Isso indica que o valor do elemento ou atributo deve ser uma string, deve ser exatamente seis caracteres em uma linha, e esses caracteres deve ser um número de 0 a 9.