De acordo com as Leis 12.965/2014 e 13.709/2018, que regulam o uso da Internet e o tratamento de dados pessoais no Brasil, ao me inscrever na newsletter do portal DICAS-L, autorizo o envio de notificações por e-mail ou outros meios e declaro estar ciente e concordar com seus Termos de Uso e Política de Privacidade.

Tutorial XML-Schema

Colaboração: Maurício M. Maia

Data de Publicação: 26 de Março de 2005

Este documento é uma tradução do tutorial do W3Schools, disponível em http://www.w3schools.com/schema/default.asp
XML Schema é uma alternativa ao DTD. Neste tutorial, você vai aprender o que é um XML Schema, como ele substitui o DTD, e como usá-lo em suas aplicações.

Introdução ao XML Schema

XML Schema é uma alternativa ao DTD baseada em XML.

Um esquema XML descreve a estrutura de um documento XML.

A linguagem XML Schema também é chamada de XML Schema Definition (XSD).

O que você já precisa saber

Antes de estudar a Linguagem XML Schema, você deve ter um entendimento básico de XML e Namespaces XML. Também é válido um entendimento básico de DTD.

Se você deseja estudar estes assuntos primeiro, visite o tutorial XML e o tutorial DTD.

O que é um XML Schema?

O propósito de um XML Schema é definir os blocos de construção permitidos em um documento XML, como um DTD.

Um XML Schema:

  • define elementos que podem aparecer em um documento
  • define atributos que podem aparecer em um documento
  • define que elementos são elementos filhos
  • define a ordem dos elementos filhos
  • define o número de elementos filhos
  • define se um elemento é vazio ou pode incluir texto
  • define tipos de dados para elementos e atributos
  • define valores padrão e fixos para elementos e atributos

XML Schemas são sucessores das DTDs

Nós acreditamos que logo XML Schemas vão ser usados na maioria das aplicações Web no lugar de DTDs. Aqui estão algumas razões:

  • XML Schemas são extensíveis para adições futuras
  • XML Schemas são mais ricos e úteis que DTDs
  • XML Schemas são escritos em XML
  • XML Schemas suportam tipos de dados
  • XML Schemas suportam namespaces

XML Schema é uma Recomendação do W3C

XML Schema foi originalmente proposto pela Microsoft, mas se tornou um recomendação oficial do W3C em Maio de 2001. A especificação está estável e foi revisada pelos membros do W3C. Para uma visão geral das atividades e status do W3C, visite o tutorial W3C

XML Schemas - Por que?

Há muitas razões para XML Schema ser melhor que DTD.

XML Schema tem suporte a tipos de dados

Uma das grandes vantagens de XML Schemas é o suporte a tipos de dados:

  • É mais fácil descrever conteúdo de documentos permissíveis
  • É mais fácil validar os dados
  • É mais fácil trabalhar com dados de um banco de dados
  • É mais fácil definir restrições aos dados
  • É mais fácil definir padrões/formatos de dados
  • É mais fácil converter dados entre diferentes tipos

XML Schemas usa sintaxe XML

Outra grande força do XML Schema é ser escrito em XML.

Por isso:

  • Você não tem que aprender outra linguagem
  • Você pode usar seu editor XML para editar seus arquivos XML Schema
  • Você pode usar seu parser XML para verificar seus arquivos XML Schema
  • Você pode manipular seu XML Schema com XML DOM
  • Você pode usar seu XML Schema com XSLT

Comunicação segura de dados com XML Schemas

Quando um dado é enviado de um ponto para outro é essencial que as duas parte tem a mesma expectativa sobre o conteúdo.

Com XML Schemas, o remetente pode descrever o dado de forma que o receptor vá entender.

Uma data como "03-11-2004" vai, em alguns países, ser interpretada como 3 de Novembro e em outros com 11 de Março, mas um elemento XML com um tipo de dado como esse:

  
  <date type="date">2004-03-11</date>

assegura um entendimento mútuo do conteúdo porque o o tipo de dado XML requer o formato YYYY-MM-DD.

XML Schemas são extensíveis

XML Schemas são extensíveis, assim como XML, porque eles são escritos em XML.

Com uma definição extensível você pode:

  • Reutilizar seu Schema em outros Schemas
  • Criar seus próprios tipos de dados derivados dos tipos padrões
  • Referenciar múltiplos esquemas em um mesmo documento

Bem formado não é o bastante

Um documento XML bem formado é um documento que atende às regras de sintaxe XML:

  • deve começar com um declaração XML
  • deve ter um elemento raiz único
  • todas tags abertas precisam ser fechadas
  • tags XML são sensíveis à caixa alta/baixa
  • todo elemento deve ser fechado
  • todo elemento tem que ser propriamente aninhado
  • todos valores de atributos precisam estar entre aspas
  • entidades XML devem ser usadas para caracteres especiais

Mesmo se os documentos são bem formados eles podem conter erros, e estes erros podem ter conseqüências sérias. Imagine essa situação: você compra 5 tonners de impressoras laser, ao invés de 5 impressoras laser. Com XML Schemas, a maioria destes erros podem ser detectados pelo seu software de validação.

XSD How To

Documentos XML podem referenciar um DTD ou um XML Schema.

Um documento XML simples

Veja este documento XML chamado "note.xml":

  
  <?xml version="1.0">
  <note>
  <to>Tove</to>
  <from>Jani</from>
  <heading>Reminder<heading>
  <body>Don't forget me this weekend!</body>
  </note>

Um DTD simples

Este é um arquivo DTD chamado "note.dtd" que define os elementos do documento XML acima ("note.xml"):

  
  <!ELEMENT note (to, from, heading, body)>
  <!ELEMENT to (#PCDATA)>
  <!ELEMENT from (#PCDATA)>
  <!ELEMENT heading (#PCDATA)>
  <!ELEMENT body (#PCDATA)>

A linha 1 define que o elemento note possui 4 elementos: "to, from, heading, body". Linhas 2 a 5 o elemento to como sendo do tipo "#PCDATA", o elemento from como "#PCDATA", e assim por diante...

Um XML Schema simples

Este é um arquivo XML Schema chamado "note.xsd" que define os elementos do documento XML acima ("note.xml"):

  
  ?xml version="1.0"?>
  <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
  targetNamespace="http://www.w3schools.com"
  xmlns="http://www.w3schools.com"
  elementFormDefault="qualified">
  
  <xs:element name="note">
     <xs:complexType>
       <xs:sequence>
         <xs:element name="to" type="xs:string"/>
         <xs:element name="from" type="xs:string"/>
         <xs:element name="heading" type="xs:string"/>
         <xs:element name="body" type="xs:string"/>
       </xs:sequence>
     </xs:complexType>
  </xs:element>
  
  </xs:schema>

O elemento note é dito um tipo complexo porque contém outros elementos. Os outros elementos são ditos tipos simples porque não contém outros elementos. Você vai aprender mais sobre tipos simples e complexo nos próximos capítulos.

Uma referência para um DTD

Este documento XML tem uma referência para um DTD:

  
  <?xml version="1.0"?>
  
  <!DOCTYPE note SYSTEM
  "http://www.w3schools.com/dtd/note.dtd">
  
  <note>
  <to>Tove</to>
  <from>Jani</from>
  <heading>Reminder</heading>
  <body>Don't forget me this weekend!</body>
  </note>

Uma referência a um XML Schema

Este documento contém uma referência a um XML Schema:

  
  <?xml version="1.0"?>
  
  <note
  xmlns="http://www.w3schools.com"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://www.w3schools.com note.xsd">
  
  <to>Tove</to>
  <from>Jani</from>
  <heading>Reminder</heading>
  <body>Don't forget me this weekend!</body>
  </note>

XSD - O elemento <schema>

O elemento <schema> é o elemento raiz de todo XML Schema!

O elemento <schema>

O elemento <schema> é o elemento raiz de todo XML Schema:

  
  <?xml version="1.0"?>
  
  <xs:schema>
  
  ...
  ...
  
  </xs:schema>

O elemento <schema> pode conter alguns atributos. Uma declaração de Schema geralmente parece com isto:

  
  <?xml version="1.0"?>
  
  <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
  targetNamespace="http://www.w3schools.com"
  xmlns="http://www.w3schools.com"
  elementFormDefault="qualified">
  
  ...
  ...
  
  </xs:schema>

O seguinte fragmento:

  
  <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"

indica que os elementos e tipos de dados usados no esquema (schema, element, complexType, sequence, string, boolean, etc.) vêm do namespace "http://www.w3.org/2001/XMLSchema". Ele também especifica que os elementos e tipos de dados que vêm de "http://www.w3.org/2001/XMLSchema" devem ser prefixados com xs: !!

Este fragmento:

  
  targetNamespace="http://www.w3schools.com"

indica que os elementos definidos por este esquema (note, to, from, heading, body) vêm do namespace "http://www.w3schools.com" .

Este fragmento:

  
  xmlns="http://www.w3schools.com"

indica que o namespace padrão é "http://www.w3schools.com".

Este fragmento:

  
  elementFormDefault="qualified">

indica que todo elemento usado por uma instância de documento XML que foi declarado neste esquema deve ser qualificado pelo namespace.

Referenciando um Schema em um documento XML

Este documento XML tem uma referência para um XML Schema:

  
  <?xml version="1.0"?>
  
  <note xmlns="http://www.w3schools.com"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://www.w3schools.com note.xsd">
  
  <to>Tove</to>
  <from>Jani</from>
  <heading>Reminder</heading>
  <body>Don't forget me this weekend!</body>
  </note>

Este fragmento:

  
  xmlns="http://www.w3schools.com"

especifica a declaração de namespace padrão. Esta declaração diz ao validador de esquema que os elementos usados neste documento XML são declarados no namespace "http://www.w3schools.com".

Uma vez que você tem uma instância XML Schema do namespace disponível:

  
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

você pode usar o atributo schemaLocation. Este atributo tem dois valores. O primeiro é o namespace usado. O segundo é a localização do esquema XML para se usado pelo namespace:

  
  xsi:schemaLocation="http://www.w3schools.com note.xsd">

Elementos XSD Simples

XML Schemas define os elementos de um arquivo XML.

Um elemento simples é um elemento XML que contém apenas texto. Ele não pode conter outros elementos ou atributos.

O que é um elemento simples

Um elemento simples é um elemento XML que contém apenas texto. Ele não pode conter outros elementos ou atributos.

Entretanto, a restrição "apenas texto" é pouco clara. O texto pode ser de diferentes tipos. Pode ser um dos tipos inclusos na definição de XML Schema (boolean, string, date, etc.), ou um tipo personalizado que você mesmo pode definir.

Como definir um elemento simples

A sintaxe para definir um elemento simples é:

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

onde xxx é o nome do elemento e yyy é o tipo de dado do elemento.

Aqui está alguns elementos XML:

  
  <lastname>Refsnes</lastname>
  <age>34</age>
  <dateborn>1968-03-27</dateborn>

E aqui as definições correspondentes:

  
  <xs:element name="lastname" type"xs:string"/>
  <xs:element name="age" type="xs:integer"/>
  <xs:element name="dateborn" type="xs:date"/>

Tipos de dados XML Schema comuns

XML Schema tem vários tipos de dados próprios. Aqui está uma lista dos mais comuns:

  • xs:string
  • xs:decimal
  • xs:integer
  • xs:boolean
  • xs:date
  • xs:time

Declare valores padrão e fixos para elementos simples

Elementos simples podem ter um conjunto de valores padrão OU um fixos.

Um valor padrão é automaticamente atribuído ao elemento quando nenhum outro valor é especificado. No exemplo seguinte, o valor padrão é "red":

  
  <xs:element name="color" type="xs:string" default="red"/>

Um valor fixo também é atribuído automaticamente ao elemento. Você não pode especificar outro valor. No exemplo a seguir, o valor fixo é "red":

  
  <xs:element name="color" type="xs:string" fixed="red"/>

Atributos XSD

Todos atributos são declarados como tipos simples.

Apenas elementos complexos tem atributos!

O que é um atributo?

Elementos simples não podem ter atributos. Se um elemento tem atributos, ele é considerado do tipo complexo. Mas atributos são declarados como tipos simples. Isso significa que um elemento com atributos sempre tem uma definição do tipo complexo.

Como definir um atributo

A sintaxe para definir um atributo é:

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

onde xxx é o nome do atributo e yyy é o tipo de dado do atributo.

Aqui está um elemento XML com um atributo:

  
  <lastname lang="EN>Smith</lastname>

E aqui a definição correspondente do atributo:

  
  <xs:attribute name="lang" type="xs:string"/>

Tipos de dados comuns do XML Schema

XML Schema tem vários tipos de dados próprios. Aqui está uma lista dos mais comuns:

  • xs:string
  • xs:decimal
  • xs:integer
  • xs:boolean
  • xs:date
  • xs:time

Declare valores padrão e fixo para atributos

Atributos podem ter valores padrão OU fixo especificados.

Um valor padrão é atribuído automaticamente ao atributo quando nenhum outro valor é especificado. No exemplo seguinte, o valor padrão é "EN":

  
  <xs:attribute name="lang" type="xs:string" default="EN">

Um valor fixo é atribuído automaticamente ao atributo. Você não pode especificar outro valor. No exemplo seguinte, o valor fixo é "EN":

  
  <xs:attribute name="lang" type="xs:string" fixed="EN"/>

Criando atributos opcionais e obrigatórios

Todos atributos são opcionais por padrão. Para especificar explicitamente que um atributo é opcional, utilize o atributo "use":

  
  <xs:attribute name="lang" type="xs:string" use="optional"/>

Para fazer um atributo obrigatório:

  
  <xs:atrribute name="lang" type="xs:string" use="required"/>

Restrições de conteúdo

Quando um elemento ou um atributo XML tem um tipo definido, isto cria uma restrição ao conteúdo dele. Se um elemento XML é do tipo "xs:date" e contém um string como "Hello Mother", o elemento não vai ser validado.

Mas, há mais... com XML Schemas, você pode adicionar suas próprias restrições aos seus elementos e atributos XML. Estas restrições são chamadas facets. Você pode ler mais sobre facets no próximo capítulo.

Restrições/facets XSD

Restrições são usadas para controlar os valores aceitos para elementos e atributos XML. Restrições em elementos XML são chamados facets.

Restrições em valores

Este exemplo define um elemento chamado "age" com um restrição. O valor de age não pode ser menor que 0 ou maior que 100:

  
  <xs:element name="age">
  
  <xs:simpleType>
     <xs:restriction base="xs:integer">
         <xs:minInclusive value="0"/>
         <xs:maxInclusive value="100"/>
     </xs:restriction>
  </xs:simpleType>
  
  </xs:element>

Restrições em conjuntos de valores

Para limitar o conteúdo de um elemento XML em um conjunto de valores aceitáveis, nós podemos usar restrições enumeradas.

Este exemplo define um elemento chamado "car":

  
  <xs:element name="car">
  
  <xs:simpleType>
     <xs:restriction base="xs:string">
         <xs:enumeration value-"Audi"/>
         <xs:enumeration value="Golf"/>
         <xs:enumeration value="BMW"/>
     </xs:restriction>
  </xs:simpleType>
  
  </xs:element>

O elemento "carro" é um tipo simples com restrição. Os valores aceitáveis são: Audi, Golf, BMW.

O exemplo acima também poderia ser escrito assim:

  
  <xs:element name="car" type="carType">
  
  <xs:simpleType name="carType">
     <xs:restriction base="xs:string">
         <xs:enumeration value="Audi"/>
         <xs:enumeration value="Golf"/>
         <xs:enumeration value="BMW"/>
     </xs:restriction>
  <xs:simpleType>

Nota: Neste caso o tipo "carType" pode ser usado por outros elementos, porque ele não é parte do elemento "car".

Restrições em séries de valores

Para limitar o conteúdo de um elemento XML em uma série de números ou letras, podemos utilizar a restrição de padrão.

Este exemplo define o elemento chamado "letter":

  
  <xs:element name="letter">
  
  <xs:simpleType>
     <xs:restriction base="xs:string">
         <xs:pattern value="[a-z]"/>
     </xs:restriction>
  </xs:simpleType>
  
  </xs:element>

O elemento "letter" é do tipo simples com uma restrição. O único valor aceitável é UMA das letras MINÚSCULAS de a até z.

O próximo exemplo define um elemento chamado "initials":

  
  <xs:element name="initials">
  
  <xs:simpleType>
     <xs: restriction base="xs:string">
         <xs:pattern value="[A-Z][A-Z][A-Z]"/>
     <xs:restriction>
  </xs:simpleType>
  
  <xs:element>

O elemento "initials" é simples com um restrição. O único valor aceitável são TRÊS letras MAiÚSCULAS de a até z.

Este exemplo também define um elemento chamado "initials":

  
  <xs:element name="initials">
  
  <xs:simpleType>
     <xs:restriction base="xs:string">
         <xs:patter value="[a-zA-Z][a-zA-Z][a-zA-Z]"/>
     </xs:restriction>
  <xs:simpleType>
  
  <xs:element>

O elemento "initials" é do tipo simples com restrição. O único valor aceitável são TRÊS letras MINÚSCULAS ou MAIÚSCULAS de a até z.

Este exemplo define um elemento chamado "choice":

  
  <xs:element name="choice">
  
  <xs:simpleType>
     <xs:restriction base="xs:string">
         <xs:pattern value="[xyz]"/>
     </xs:restriction>
  </xs:simpleType>
  
  </xs:element>

O elemento "choice" é um tipo simples com restrição. O único valor aceitável é UMA das seguintes letras: x, y, OU z.

O próximo exemplo define um elemento chamado "prodid":

  
  <xs:element name="prodid">
  
  <xs:simpleType>
     <xs:restriction base="xs:integer">
         <xs:patter value="[0-9][0-9][0-9][0-9][0-9]"/>
     </xs:restriction>
  </xs:simpleType>
  
  </xs:element>

O elemento "prodid" é um tipo simples com restrição. O único valor aceitável são CINCO dígitos em seqüência, e cada dígito deve estar entre 0 e 9.

Outras restrições em séries de valores

Algumas outras restrições que podem ser definidas por restrição de padrão:

Este exemplo define um elemento chamado "letter":

  
  <xs:element name="letter">
  
  <xs:simpleType>
     <xs:restriction base="xs:string">
         <xs:pattern value="([a-z])*"/>
     </xs:restriction>
  </xs:simpleType>
  
  </xs:element>

O elemento "letter" é um tipo simples com restrição. O valor aceitável é zero ou mais ocorrências de letras minúsculas de a até z.

Este exemplo também define um elemento chamado "letter":

  
  <xs:element name="letter">
  
  <xs:simpleType>
     <xs:restriction base="xs:string">
         <xs:pattern value="([a-z][A-Z])+"/>
     </xs:restriction>
  </xs:simpleType>
  
  </xs:element>

O elemento "letter" é um tipo simples com um restrição. O valor aceitável é uma ou mais ocorrências de um letra minúscula seguida de uma letra maiúscula de a até z.

Este exemplo define um elemento chamado "gender":

  
  <xs:element name="gender">
  
  <xs:simpleType>
     <xs:restriction base="xs:string">
         <xs:pattern value="male|female"/>
     </xs:restriction>
  </xs:simpleType>
  
  </xs:element>

O elemento "gender" é um tipo simples com uma restrição. O único valor aceitável é male OU female.

Este exemplo define um elemento chamado "password":

  
  <xs:element name="password">
  
  <xs:simpleType>
     <xs:restriction base="xs:string">
         <xs:pattern value="[a-zA-Z0-9]{8}"/>
     </xs:restriction>
  </xs:simpleType>
  
  <xs:element>

O elemento "password" é um tipo simples com um restrição. Deve haver exatamente oito caracteres e estes caracteres devem ser letras minúsculas ou maiúsculas de a até x, ou um número de 0 a 9.

Restrições em caracteres vazios

Para especificar como um caractere vazio deve ser tratado, devemos usar a restrição whiteSpace.

Este exemplo define um elemento chamado "adderess":

  
  <xs:element name="adress">
  
  <xs:simpleType>
     <xs:restriction base="xs:string">
         <xs:whiteSpace value="preserve"/>
     <xs:restriction>
  </xs:simpleType>
  
  </xs:element>

O elemento "adress" é um tipo simples com um restrição. A restrição whiteSpace é definida como "preserve", qu significa que o processador XML NÂO VAI remover nenhum caractere vazio.

Este exemplo também define um elemento chamado "address":

  
  <xs:element name="address">
  
  <xs:simpleType>
     <xs:restriction base="xs:string">
         <xs:whiteSpace value="replace"/>
     </xs:restriction>
  </xs:simpleType>
  
  </xs:element>

Este elemento "address" é um tipo simples com um restrição. A restrição whiteSpace é definida como "replace", que significa que o processador XML VAI SUBSTITUIR todos caracteres vazios (quebras de linha, tabs, espaços) com espaços.

Este exemplo também define um elemento chamado "address":

  
  <xs:element name="address">
  
  <xs:simpleType>
     <xs:restriction base="xs:string">
         <xs:whiteSpace value="collapse"/>
     </xs:restriction>
  </xs:simpleType>
  
  </xs:element>

Este elemento "address" é um tipo simples com uma restrição. A restrição whiteSpace é definida como "collapse", que significa que o processador XML VAI REMOVER todos caracteres vazios (quebras de linha, tabs, espaços são substituídos com espaços, espaços iniciais e finais são removidos, espaços múltiplos são reduzidos a um).

Restrições de comprimento

Para limitar o comprimento de um elemento, nós usamos as restrições de comprimento, maxLength e minLength.

Este exemplo define um elemento chamado "password":

  
  <xs:element name="password">
  
  <xs:simpleType>
     <xs:restriction base="xs:string">
         <xs:length value="8"/>
     </xs:restriction>
  </xs:simpleType>
  
  </xs:element>

O elemento "password" é um tipo simples com uma restrição. O valor deve ter exatamente oito caracteres.

Este exemplo define outro elemento chamado "password":

  
  <xs:element name="password">
  
  <xs:simpleType>
     <xs:restriction base="xs:string">
         <xs:minLength value="5"/>
         <xs:maxLength value="8"/>
     </xs:restriction>
  </xs:simpleType>
  
  </xs:element>

Este elemento "password" é um tipo simples com uma restrição. O valor deve ter no mínimo cinco e no máximo oito caracteres.

Restrições para tipos de dados

Restrição Descrição
enumeration Define uma lista de valores válidos
fractionDigits Especifica o número máximo casas decimais permitidas. Deve ser igual ou maior que zero
length Especifica o número exato de caracteres ou itens permitidos. Deve ser igual ou maior que zero
maxExclusive Especifica o valor máximo para valores numéricos (o valor deve ser menor que este valor)
maxInclusive Especifica o valor máximo para valores numéricos (o valor deve ser menor ou igual a este valor)
maxLength Especifica o número máximo de caracteres ou itens permitidos. Deve ser igual ou maior que zero
minExclusive Especifica o valor mínimo para valores numéricos (o valor deve ser maior que este valor)
minInclusive Especifica o valor mínimo para valores numéricos (o valor deve ser maior ou igual a este valor)
minLength Especifica o número mínimo de caracteres ou itens permitidos. Deve ser igual ou maior que zero
pattern Define a seqÜência exata de caracteres permitidos
totalDigits Especifica o número exato de digitos permitidos. Deve ser maior que zero
whiteSpace Especifica como caracteres vazios (tabs, espaços e retornos de carro) são tratados

Elementos XSD complexos

Um elemento complexo contém outros elementos e/ou atributos.

O que é um elemento complexo ?

Um elemento complexo é um elemento XML que contém outros elementos e/ou atributos.

Há quatro tipos de elementos complexos:

  • elementos vazios
  • elementos que contém apenas outros elementos
  • elementos que contém apenas texto
  • elementos que contém tanto outros elementos quanto texto

Nota: Cada um desses elementos podem conter atributos também!

Exemplos de elementos XML complexos

Um elemento XML complexo, "product", que é vazio:

  
  <product pid="1245"/>

Um elemento XML complexo, "employee", que contém apenas outros elementos:

  
  <employee>
  <firstname>John</firstname>
  <lastname>Smith</lastname>
  </employee>

Um elemento XML complexo, "food", que contém apenas texto:

  
  <food type="dessert">Ice cream</food>

Um elemento XML complexo, "description", que contém outros elementos e texto:

  
  <description>
  It happened on <date lang="norwegian">03.03.99</date> ....
  </description>

Como definir um elemento complexo

Observe este elemento XML complexo, "employee", que contém apenas outros elementos:

  
  <employee>
  <firstname>John</firstname>
  <lastname>Smith</lastname>
  </employee>

Nós podemos definir um elemento complexo em um XML Schema de diferente maneiras:

1. O elemento "employee" pode ser declarado diretamente, nomeando o elemento:

  
  <xs:element name="employee">
     <xs:complexType>
         <xs:sequence>
             <xs:element name="firstname" type="xs:string"/>
             <xs:element name="lastname" type="xs:string"/>
         <xs:sequence>
     </xs:complexType>
  </xs:element>

Se você usar o método descrito acima, apenas o elemento "employee" pode usar o tipo complexo definido. Note que os elementos filhos, "firstname" e "lastname", são envolvidos pelo indicador <sequence>. Isto significa que os elementos filhos devem aparecer na mesma ordem da declaração: "firstname" primeiro e "lastname" depois. Você vai aprender sobre indicadores no capítulo Indicadores XSD;

2. O elemento "employee" pode ter um atributo tipo que faz referência ao nome do tipo complexo que deve ser usado:

  
  <xs:element name="employee" type="personinfo"/>
  
  <xs:complexType name="personinfo">
     <xs:sequence>
         <xs:element name="firstname" type="xs:string"/>
         <xs:element name="lastname" type="xs:string/">
     </xs:sequence>
  </xs:complexType>

Se você usar o método descrito acima, vários elementos podem fazer referência ao mesmo tipo complexo, assim:

  
  <xs:element name="employee" type="personinfo"/>
  <xs:element name="student" type="personinfo"/>
  <xs:element name="member" type="personinfo"/>
  
  <xs:complexType name="personinfo">
     <xs:sequence>
         <xs:element name="firstname" type="xs:string"/>
         <xs:element name="lastname" type="xs:string"/>
     </xs:sequence>
  </xs:complexType>

Você também pode basear um elemento do tipo complexo em um tipo complexo existente e adicionar alguns elementos, assim:

  
  <xs:element name="employee" type="fullpersoninfo"/>
  
  <xs:complexType name="personinfo">
     <xs:sequence>
         <xs:element name="firstname" type="xs:string"/>
         <xs:element name="personinfo" type="xs:string"/>
     </xs:sequence>
  </xs:complexType>
  
  <xs:complexType name="fullpersoninfo">
     <xs:complexContent>
         <xs:extension base="personinfo">
             <xs:sequence>
                 <xs:element name="address" type="xs:string"/>
                 <xs:element name="city" type="xs:string"/>
                 <xs:element name="country" type="xs:string"/>
             </xs:sequence>
         </xs:extension>
     </xs:complexContent>
  <xs:complexType>

Elementos complexos vazios

Um elemento complexo vazio pode conter atributos; mas não pode ter nenhum conteúdo entre as tags de abertura e fechamento.

Defina tipos complexos para elementos vazios

Um elemento XML vazio:

  
  <product prodid="1345"/>

O elemento "product" acima não tem conteúdo. Para definir um tipo sem conteúdo, nós devemos definir um tipo que permita apenas elementos em seu conteúdo, mas nós não declaramos nenhum elemento realmente, assim:

  
  <xs:element name="product">
     <xs:complexType>
         <xs:complexContent>
             <xs:restriction base="xs:integer">
                 <xs:attribute name="prodid" type="xs:positiveInteger"/>
             </xs:restriction>
         </xs:complexContent>
     </xs:complexType>
  </xs:element>

No exemplo acima, nós definimos um complexType tento complexContent, i.e. apenas elementos. O elemento complexContent diz que queremos restringir ou extender o modelo de conteúdo de um tipo complexo, e a restrição de inteiros declara um atributo mas não cria nenhum elemento.

Entretanto, é possível declarar o elemento product de forma mais compacta, assim:

  
  <xs:element name="product">
     <xs:complexType>
         <xs:attribute name="prodid" type="xs:positiveInteger"/>
     </xs:complexType>
  </xs:element>

Ou você pode dar um nome ao complexType, e fazer o elemento "product" ter um tipo que faz referência ao nome do complexType (se você usar este método, vários elementos podem referenciar o mesmo tipo complexo):

  
  <xs:element name="product" type="prodtype"/>
  
  <xs:complexType name="prodtype">
     <xs:atrribute name="prodid" type="xs:positiveInteger"/>
  </xs:complexType>

Tipos complexos apenas elementos

Um tipo complexo "apenas elementos" contém um elemento que contém apenas outros elementos.

Defina tipos complexos apenas com elementos

Um elemento XML, "person", que contém apenas outros elementos:

  
  <person>
  <firstname>John</firstname>
  <lastname>Smith</lastname>
  </person>

Você pode definir o elemento "person" em um esquema, assim:

  
  <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>

Note a tag <xs:sequence>. Isto significa que os elementos definidos ("firstname" e "lastname") devem aparecer nesta ordem dentro do elemento "person".

Ou você pode dar um nome ao complexType, e um atributo type ao elemento "person" que faz referência a ele (se você usar este método, vários elementos podem referenciar o mesmo tipo complexo).

  
  <xs:element name="person" type="persontype"/>
  
  <xs:complexType name="persontype">
     <xs:sequence>
         <xs:element name="firstname" type="xs:string"/>
         <xs:element name="lastname" type="xs:string"/>
     </xs:sequence>
  </xs:complexType>

Elementos complexos apenas texto

Um elemento complexo texto pode conter tanto atributos quanto texto.

Defina um elemento complexo apenas texto

Este tipo contém apenas conteúdo simples (texto e atributos), assim nós adicionamos um elemento simpleContent em torno do conteúdo. Quando usar conteúdo simples, você precisa definir uma extensão OU uma restrição com o elemento simpleContent, assim:

  
  <xs:element name="somename">
     <xs:complexType>
         <xs:simpleContent>
             <xs:extension base="basetype">
                 ....
                 ....
             </xs:extension>
         </xs:simpleContent>
     </xs:complexType>
  </xs:element>
  
  OU
  
  <xs:element name="somename">
     <xs:complexType>
         <xs:simpleContent>
             <xs:restriction base="basetype">
                 ....
                 ....
             </xs:restriction>
         </xs:simpleContent>
     </xs:complexType>
  </xs:element>

Dica: Use o elemento extension para expandir o tipo simples base de um elemento, e o elemento restriction para limitá-lo.

Aqui está um exemplo de um elemento XML, "shoesize", que contém apenas texto:

  <shoesize country="france">35</shoesize>

O exemplo a seguir declara um complexType, "shoesize". O conteúdo é definido como tipo de dado integer e o elemento "shoesize" também contém um atributo chamado "country":

  
  <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>

Nós também poderíamos definir um nome para o complexType, e especificar um atributo type ao elemento "shoesize" que faz referência ao nome do complexType (se você usar este método, vários elementos podem referenciar o mesmo tipo complexo):

  
  <xs:element name="shoesize" type="shoetype"/>
  
  <xs:complexType name="shoetype">
     <xs:simpleContent>
         <xs:extension base="xs:integer">
             <xs:attribute name="country" type="xs:string"/>
         </xs:extension>
     </xs:simpleContent>
  </xs:complexType>

Tipos complexos com conteúdo misto

Um elemento do tipo complexo misto pode conter atributos, elementos, e texto.

Defina tipos complexos com conteúdo misto

Um elemento XML, "letter", que contém tanto outros elementos quanto texto:

  
  <letter>
  Dear Mr.<name>John Smith</nam>
  Your order <orderid>1032</orderid>
  wil be shipped on <shipdate>2001-07-13</shipdate>.
  </letter>

Note o texto que aparece entre os elementos. "name", "orderid", e "shipdate" são todos filhos de "letter". O seguinte esquema declara o elemento "letter":

  
  <xs:element name="letter">
     <xs:complexType mixed="true">
         <xs:sequence>
             <xs:element name="name" type="xs:string"/>
             <xs:element name="orderid" type="xs:positiveInteger"/>
             <xs:element name="shipdate" type="xs:date"/>
         </xs:sequence>
     </xs:complexType>
  <xs:element>

Nota: Para permitir que caracteres apareçam entre os elementos filhos de "letter", o atributo mixed deve ser definido como "true". A tag <xs:sequence> significa que os elementos definidos (name, orderid e shipdate) devem parecer nesta ordem no elemento "letter".

Nós também poderíamos dar um nome ao elemento complexType, e definir o atributo type de "letter" como uma referência a ele (se você usar este método, vários elementos podem fazer referência ao mesmo complexType):

  
  <xs:element name="letter" type="lettertype"/>
  
  <xs:complexType name="lettertype" mixed="true">
     <xs:sequence>
         <xs:element name="name" type="xs:string"/>
         <xs:element name="orderid" type="xs:positiveInteger"/>
         <xs:element name="shipdate" type="xs:date"/>
     </xs:sequence>
  </xs:complexType>

Indicadores de tipos complexos

Nós podemos controlar COMO os elementos serão usados em documentos através de indicadores.

Indicadores

Nós temos sete tipos de indicadores:

Indicadores de ordem:

  • All
  • Choice
  • Sequence

Indicadores de ocorrência:

  • maxOccurs
  • minOccurs

Indicadores de grupo:

  • Group name
  • attributeGroup name

Indicadores de ordem

Indicadores de ordem são usados para definir a ordem em que os elementos ocorrem.

Indicador All

O indicador <all> especifica por padrão que os elementos filhos podem aparecer em qualquer ordem e que cada um deve ocorrer, e apenas uma vez:

  
  <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>

Nota: Usando o indicador <all> você pode especificar o indicador <minOccurs> em 0 ou 1 e <maxOccurs> só pode ser 1 (<minOccurs> e <maxOccurs> são descritos adiante).

Indicador choice

O indicador <choice> especifica que um elemento filho ou outro pode ocorrer:

  
  <xs:element name="person">
     <xs:complexType>
         <xs:choice>
             <xs:element name="employee" type="employee"/>
             <xs:element name="member" type="member"/>
         </xs:choice>
     </xs:complexType>
  </xs:element>

Indicador sequence

O indicador <sequence> especifica que os elementos filhos devem aparecer em uma ordem específica:

  
  <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>

Indicadores de ocorrência

Indicadores de ocorrência são usados para indicar com que freqüência um elemento pode ocorrer.

Nota: Para todos indicadores "Order" e "Group" (any, all, choice, sequence, group, name, e group reference) o valor padrão de maxOccurs e minOccurs é 1!!!

Indicador maxOccurs

O indicador <maxOccurs> especifica o número máximo de vezes que um elemento pode ocorrer:

  
  <xs:element name="person">
     <xs:complexType>
         <xs:sequence>
             <xs:element name="full_name" type="xs:string"/>
             <xs:element name="child_name" name="child_name" type="xs:string" maxOccurs="10"/>
         </xs:sequence>
     </xs:complexType>
  </xs:element>

O exemplo acima indica que o elemento "child_name" pode ocorre no mínimo uma vez (o valor padrão para minOccurs é 1) e no máximo dez vezes em um elemento "person".

Indicador minOccurs

O indicador <minOccurs> especifica o número mínimo de vezes que um elemento pode ocorrer:

  
  <xs:element name="person">
     <xs:complexType>
         <xs:sequence>
             <xs:element name="full_name" type="xs:string"/>
             <xs:element name="child_name" type="xs:string"
             maxOccurs="10" minOccurs="0"/>
         </xs:sequence>
     </xs:complexType>
  </xs:element>

O exemplo acima indica que o elemento "child_name" pode ocorrer um mínimo de zero vezes e um máximo de dez em um elemento "person".

Para permitir que um elemento pareça um número ilimitado de vezes, use a instrução maxOccurs="unbounded":

Um exemplo prático

Um arquivo XML chamado "Myfamily.xml":

  
  <?xml version="1.0" encoding="ISO-8859-1"?>
  
  <persons xmlns:xs="http://www.w3.org/2001/XMLSchema-instance"
  xsi:noNamespaceSchemaLocation="family.xsd">
  
  <person>
  <full_name>Hege Refsnes</full_name>
  <child_name>Cecilie</child_name>
  </person>
  
  <person>
  <full_name>Tove Refsnes</full_name>
  <child_name>Hege</child_name>
  <child_name>Stale</child_name>
  <child_name>Jim</child_name>
  <child_name>Borge</child_name>
  </person>
  
  <person>
  <full_name>Stale Refsnes</full_name>
  </person>
  
  </persons>

O arquivo XML acima contém um elemento raiz chamado "persons". Dentro deste elemento está definido vários elementos "person". Cada elemento "person" deve conter um elemento filho "full_name" e pode conter até cinco elementos filho "child_name".

Aqui está o esquema "family.xsd":

  
  <xml version="1.0" encoding="ISO-8859-1"?>
  <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
  elementFormDefault="qualified">
  
  <xs:element name="persons">
     <xs:complexType>
         <xs:sequence>
             <xs:element name="person" maxOccurs="unbounded">
                 <xs:complexType>
                     <xs:sequence>
                         <xs:element name="full_name" type="xs:string"/>
                         <xs:element name="child_name" type="xs:string"
                         minOccurs="0" maxOccurs="5"/>
                     </xs:sequence>
                 </xs:complexType>
             </xs:element>
         </xs:sequence>
     </xs:complexType>
  </xs:element>
  
  </xs:schema>

Indicadores de grupo

Indicadores de grupo são usados para definir grupos de elementos relacionados.

Elementos de grupo

Elementos de grupo são definidos com a declaração group, assim:

  
  <xs:group name="groupname">
     ...
  </xs:group>

Você deve deve definir um elemento all, choice, ou sequence dentro da declaração group. O exemplo seguinte define um grupo chamado "persongroup", que define um grupo de elementos que devem ocorrer em uma seqüência exata:

  
  <xs:group name="persongroup">
     <xs:sequence>
         <xs:element name="firstname" type="xs:string"/>
         <xs:element name="lastname" type="xs:string"/>
         <xs:element name="birthday" type="xs:date"/>
     </xs:sequence>
  </xs:group>

Depois que você definiu um grupo, você pode referenciá-lo na definição de outro grupo ou tipo complexo, assim:

  
  <xs:group name="persongroup">
     <xs:sequence>
         <xs:element name="firstname" type="xs:string"/>
         <xs:element name="lastname" type="xs:string"/>
         <xs:element name="birthday" type="xs:date"/>
     </xs:sequence>
  </xs:group>
  
  <xs:element name="person" type="personinfo"/>
  
  <xs:complexType name="personinfo">
     <xs:sequence>
         <xs:group ref="persongroup"/>
         <xs:element name="country" type="xs:string"/>
     </xs:sequence>
  </xs:complexType>

Grupos de atributos

Grupos de atributos são definidos com a declaração attributeGroup, assim:

  
  <xs:attributeGroup name="groupname">
     ...
  </xs:attributeGroup>

O exemplo a seguir define um grupo de atributos chamado "personattrgroup":

  
  <xs:attributeGroup name="personattrgroup">
     <xs:attribute name="firstname" type="xs:string"/>
     <xs:attribute name="lastname" type="xs:string"/>
     <xs:attribute name="birthday" type="xs:date"/>
  </xs:attributeGroup>

Depois que você definiu um grupo de atributos, você pode referenciá-lo na definição de outro grupo ou tipo complexo, assim:

  
  <xs:attributeGroup name="personattrgroup">
     <xs:attribute name="firstname" type="xs:string"/>
     <xs:attribute name="lastname" type="xs:string"/>
     <xs:attribute name="birthday" type="xs:date"/>
  </xs:attributeGroup>
  
  <xs:element name="person"
     <xs:complexType>
         <xs:attributeGroup ref="personattrgroup"/>
     </xs:complexType>
  </xs:element>

O elemento <any>

O elemento <any> nos permite extender o documento XML com elementos não especificados no esquema.

O exemplo a seguir é um fragmento de um esquema XML chamado "family.xsd". Ele mostra uma declaração para o elemento "person". Usando o elemento <any> nós podemos extender (depois de <lastname>) o conteúdo de "person" com qualquer elemento:

  
  <xs:element name="person">
     <xs:complexType>
         <xs:sequence>
             <xs:element name="firstname" type="xs:string"/>
             <xs:element name="lastname" type="xs:string"/>
             <xs:any minOccurs="0"/>
         </xs:sequence>
     </xs:complexType>
  </xs:eleement>

Agora nós queremos extender o elemento "person" com um elemento "children". Neste caso nós podemos fazer isto, mesmo que o autor do esquema acima nunca tenha declarado o elemento "children"!

Observer esse arquivo de esquema, chamado "children.xsd":

  
  <?xml version="1.0" encoding="ISO-8859-1"?>
  <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
  targetNamespace="http://www.w3schools.com"
  xmlns="http://www.w3schools.com"
  elementFormDefault="qualified">
  
  <xs:element name="children">
     <xs:complexType>
         <xs:sequence>
             <xs:element name="childname" type="xs:string"
             maxOccurs="unbounded"/>
         </xs:sequence>
     </xs:complexType>
  </xs:element>
  
  </xs:schema>

O arquivo XML abaixo (chamado "Myfamily.xml"), usa componentes de dois esquemas diferentes; "family.xsd" e "children.xsd":

  
  <?xml version="1.0" encoding="ISO-8859-1"?>
  
  <person xmlns="http://www.microsoft.com"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:SchemaLocation="http://www.microsoft.com family.xsd
  http://www.w3schools.com children.xsd">
  
  <person>
  <firstname>Hege</firstname>
  <lastname>Refsnes</lastname>
  <children>
   <childname>Cecilie</childname>
  </children>
  </person>
  
  <person>
  <firstname>Stale</firstname>
  <lastname>Refsnes</lastname>
  </person>
  
  </persons>

O arquivo XMl acima é válido porque o esquema "family.xsd" nos permite extender o elemento "person" com um elemento opcional depois do elemento "lastname"!

Os elementos <any> e <anyAttribute> são usados para fazer documentos EXTENSÍVEIS! Eles permitem aos documentos conterem elementos adicionais que não estão declarados no esquema XML!

O elemento <anyAttribute>

O elemento <anyAttribute> nos permite extender o documento XML com atributos que não foram especificados no esquema!

O elemento <anyAttribute>

O elemento <anyAttribute> nos permite extender o documento XML com atributos que não foram especificados no esquema.

O exemplo a seguir é um fragmento de um esquema XML chamado "family.xsd". Ele mostra uma declaração para o elemento "person". Usando o elemento <anyAttribute> nós podemos adicionar qualquer número de atributos ao elemento "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:anyAttribute/>
     </xs:complexType>
  </xs:element>

Agora nós queremos extender o elemento "person" com um atributo "gender". Neste caso nós podemos fazer isto, mesmo que o autor do esquema acima nunca tenha declaro nenhum atributo "gender"!

Observe este arquivo de esquema, chamado "attribute.xsd":

  
  <?xml version="1.0" encoding="ISO-8859-1"?>
  <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
  targetNamespace="http://w3schools.com"
  xmlns="http://www.w3schools.com"
  elementFormDefault="qualified">
  
  <xs:attribute name="gender">
     <xs:simpleType>
         <xs:restriction base="xs:string">
             <xs:pattern value="male|female"/>
         </xs:restriction>
     </xs:simpleType>
  </xs:attribute>
  
  </xs:schema>

O arquivo XML abaixo (chamado "Myfamily.xml"), utiliza componentes de dois esquemas diferentes; "family.xsd" e "attribute.xsd":

  
  <?xml version="1.0" encoding="ISO-8859-1"?>
  
  <persons xmlns="http://www.microsoft.com"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:SchemaLocation="http://www.microsoft.com family.xsd
  http://www.w3schools.com attribute.xsd">
  
  <person gender="female">
  <firstname>Hege</firstname>
  <lastname>Refsnes</lastname>
  </person>
  
  <person gender="male">
  <firstname>Stale</firstname>
  <lastname>Refsnes</lastname>
  </person>
  
  </persons>

O arquivo XML acima é válido porque o esquema "family.xsd" nos permite adicionar um atributo ao elemento "person"!

Os elemento <any> e <anyAttribute> são usado para fazer documentos EXTENSÍVEIS! Eles permitem aos documentos conterem elementos adicionais que não foram declarados no esquema XML!

Substituição de elementos

Com XML Schemas um elemento pode substituir outro.

Substituição de elementos

Digamos que nós temos usuários de dois paises diferentes: Inglaterra e Noruega. Nós gostaríamos de permitir ao usuário escolher se quer usar os nomes de elementos em inglês ou norueguês no documento XML.

Para resolver este problema, nós podemos definir um substitutionGroup no esquema XML. Primeiro, nó declaramos um elemento chave e então nós declaramos outros elementos que são substituisões para o elemento chave:

  
  <xs:element name="name" type="xs:string"/>
  <xs:element name="navn" substitutionGroup="name"/>

No exemplo acima, o elemento "name" é o elemento chave e "navn" o elemento substituível para "name".

Observe esse fragmento de um esquema XML:

  
  <xs:element name="name" type="xs:string"/>
  <xs:element name="navn" substitutionGroup="name"/>
  
  <xs:complexType name="custinfo">
     <xs:sequence>
         <xs:element ref="name"/>
     </xs:sequence>
  </xs:complexType>
  
  <xs:element name="customer" type="custinfo"/>
  <xs:element name="kunde" substitutionGroup="customer"/>

Um documento XML válido (de acordo com o esquema acima) poderia parecer com isso:

  
  <customer>
     <name>John Smith</name>
  </customer>

ou com isso:

  
  <kunde>
   <navn>John Smith</navn>
  </kunde>

Bloqueando substituição de elementos

Para prevenir que outros elementos substituam um elemento específico, utilize o atributo block:

  <xs:element name="name" type="xs:string" block="substitution"/>

Observe esse fragmento de um esquema XML:

  
  <xs:element name="name" type="xs:string" block="substitution"/>
  <xs:element name="navn" substitutionGroup="name"/>
  
  <xs:complexType name="custinfo">
     <xs:sequence>
         <xs:element ref="name"/>
     </xs:sequence>
  </xs:complexType>
  
  <xs:element name="customer" type="custinfo" block="substituion"/>
  <xs:element name="kunde" substitutionGroup="customer"/>

Um documento XML válido (de acordo com o esquema acima) parece-se com isso:

  
  <customer>
   <name>John Smith</name>
  </customer>

MAS ISSO NÃO É MAIS VÁLIDO:

  
  <kunde>
   <navn>John Smith</navn>
  </kunde>

Utilizando substitutionGroup

O tipo do elemento de substituição de ver o mesmo, ou derivdo, do tipo do elemento chave. Se o tipo do elemento de substituição é o mesmo do elemento chave você não precisará especificá-lo.

Note que todos elemento em um substitutionGroup (o elemento chave e os de substituição) de ser declarados como elementos globais, caso contrário não funcionará!

O que são elementos globais?

Elementos globais são aqueles que são filhos imediatos do elemento "schema"! Elementos locais são elementos aninhados a outros elementos!

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.

Tipos de dados de string

Tipos de dados string são usados para valores que contém cadeias de caracteres.

Tipo de dado string

O tipo de dado string pode conter caracteres, quebras de linha, retornos de carro, e caracteres de tabulação.

A seguir está o exemplo de uma declaração de string em um esquema:

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

Um elemento em seu documento poderia ser assim:

  <customer>John Smith</customer>

Ou assim:

  <customer>  John Smith      </customer>

Nota: O processador XML não vai modificar o valor se você usar o tipo de dado string.

Tipo de dado normalizedString

O tipo de dado normalizedString é derivado do tipo de dado string.

Ele também contém caracteres, mas o processador XML vai removar quebras de linha, retornos de carro, e caracteres de tabulação.

A seguir está um exemplo de declaração de normalizedString em um esquema:

  <xs:element name="customer" type="xs:normalizedString"/>

Um element em seu documento poderia ser assim:

  <customer>John Smith</customer>

Ou assim:

  <customer>John Smith</customer>

Nota: No exemplo acima, o processador XML vai substituir a tabulação por espaços.

Tipo de dado token

O tipo de dado token também é derivado do tipo de dado string.

Ele também contém caracteres, mas o processador XML vai remover quebras de linha, retornos de carro, tabulação, espaços iniciais e finais, e espaços múltiplos.

A seguir está um exemplo de declaração token em um esquema:

  <xs:element name="customer" type="xs:token"/>

Um elemento em seu documento poderia ser assim:

  <customer>John Smith</customer>

Ou assim:

  <customer>  John Smith      </customer>

Nota: No exemplo acima o processador XML vai removar a tabulação.

Tipos de dados string

Name Description
ENTITIES
ENTITY
ID Uma string que representa o atributo ID em XML (usado apenas com atributos de schema)
IDREF Uma string que representa o atributo IDREF em XML (usado apenas com atributos schema)
IDREFS
language Uma string que contém a id de uma linguagem válida
Name Uma string que contém um nome XML válido
NCName
NMTOKEN Uma string que representa o atributo NMTOKEN em XML (usado apenas com atributos schema)
NMTOKENS
normalizedString Uma string que não contém quebras de linha, retornos de carro, ou tabulação
QName
string Uma cadeia de caracteres
token Um string que não contém quebras de linhs, retornos de carro, tabulação, espaços iniciais e finais, ou múltiplos espaços

Restrições em tipos de dados string

Restrições que podem ser usados com tipos de dados string:

  • enumeration
  • lenght
  • maxLength
  • minLenght
  • pattern (NMTOKENS, IDREFS, e ENTITIES não podem usar esta restrição)
  • whiteSpace

Tipos de dados de data e hora

Tipos de dados de data e hora são usados para valores que contém data e hora.

Tipo de dado date

O tipo de dado date é usado para especificar uma data.

A data é especificada da seguinte forma "YYYY-MM-DD", onde:

  • YYYY indica o ano
  • MM indica o mês
  • DD indica o dia

Nota: Todos componentes são obrigatórios!

A seguir está um exemplo de declaração uma data em um schema:

  <xs:element name="start" type="xs:date"/>

Um elemento em seu documento poderia ser assim:

  <start>2002-09-24</start>

Time zones

Para especificar um time zone (fuso horário), você pode usar uma data no horário UTC adicionando um "Z" depois da data, como aqui:

  <start>2002-09-24Z</start>

ou você pode especificar uma área do horário UTC adicionando um horário positivo ou negativo depois da data, como aqui:

  
  <start>2002-09-24-06:00</start>
  
  ou
  
  <start>2002-09-24+06:00</start>

Tipo de dado time

O tipo de dado time é usado para especificar um horário.

O horário é especificado da seguinte forma "hh:mm:ss", onde:

  • hh indica a hora
  • mm indica os minutos
  • ss indica os segundos

Nota: Todos componentes são obrigatórios!

A seguir está um exemplo de declaração de um time em em schema:

  <xs:element name="start" type="xs:time"/>

Um elemento em seu documento poderia ser assim:

  <start>09:00:00</start>

Ou assim:

  <start>09:30:10.5</start>

Time zones

Para especificar um time zone (fuso horário), você pode tanto usar um horário em UTC, adicionando um "Z" ao final dele, como aqui:

  <start>09:30:10Z</start>

ou especificando uma área do horário UTC, adicionando um horário positivo ou negativo depois dele, como aqui:

  
  <start>09:30:10-06:00</start>
  
  ou
  
  <start>09:30:10+06:00</start>

Tipo de dado dateTime

O tipo de dado dateTime é usado para especificar uma data e um horário.

O dateTime é especificado da seguinte forma "YYY-MM-DDThh:mm:ss", onde:

  • YYYY indica o ano
  • MM indica o mês
  • DD indica o dias
  • T inidica o início da seção obrigatória time
  • hh indica a hora
  • mm indica os minutos
  • ss indica os segundos

Nota: Todos componentes são obrigatórios!

A seguir está um exemplo de uma declaração dateTime em um schema:

  <xs:element name="stardate" type="xs:dateTime"/>

Um elemento em seu documento poderia ser assim:

     <startdate>2002-05-30T09:00:00</startdate>

Ou assim:

  <startdate>2002-05-30T09:30:10.5</startdate>

Time zones

Para especificar um time zone (fuso horário), você pode tanto utilizar um dateTime em UTC adicionado de um "Z", como aqui:

  <startdate>2002-05-30T09:30:10Z</startdate>

ou especificando uma área do horário UTC, adicionando um horário positivo ou negativo ao horário, como aqui:

  
  <startdate>2002-05-30T09:30:10-06:00</startdate>
  
  ou
  
  <startdate>2002-05-30T09:30:10+06:00</startdate>

Tipo de dado duration

O tipo de dado duration é usado para especificar um intervalo de tempo.

O intervalo de tempo é especificado da seguinte forma "PnYnMnDTnHnMnS", onde:

  • P indica o período (obrigatório)
  • nY indica o número de anos
  • nM indica o número de meses
  • nD indica o número de dias
  • T indica o início de uma seção de hora (obrigatório se você vai especificar horas, minutos ou segundos)
  • nH indica o número de horas
  • nM indica o número de minutos
  • nS indica o número de segundos

A seguir está um exemplo de uma declaração de duration em um schema:

  <xs:element name="period" type="duration"/>

Um elemento em seu documento poderia ser assim:

  <period>P5Y</period>

O exemplo acima indica um período de cinco anos.

Ou assim:

  <period>P5Y2M10D</period>

O exemplo acima indica um período de cinco anos, dois meses e dez dias.

Ou assim:

  <period>P5Y2M10DT15H</period>

O exemplo acima indica um período de cinco anos, dois meses, dez dias e 15 horas.

Ou assim:

  <period>PT15H</period>

O exemplo acima indica um período de 15 horas.

Duração negativa

Para especificar uma duração negativa, insira um sinal de menos antes de P:

  <period>-P10D</period>

O exemplo acima indica um período de menos 10 dias.

Tipos de dados de data e hora

Nome Descrição
date Define um valor de data
dateTime Define um valor de data e hora
duration Define um intervalo de tempo
gDay Define uma parte de uma data - o dia (DD)
gMonth Define uma parte de uma data - o mês (MM)
gMonthDay Define uma parte de uma data - o mês e o dia (MM-DD)
gYear Define uma parte de uma data - o ano (YYYY)
gYearMonth Define uma parte de uma data - o ano e o mês (YYYY-MM)
time Define um valor de hora

Restrições em tipos de dados date

Restrições que podem ser usadas com tipos de dados date:

  • enumeration
  • maxExclusive
  • maxInclusive
  • minEsclusive
  • minInclusive
  • pattern
  • whiteSpace

Tipos de dados numéricos

Tipos de dados decimais são usados para armazenar números

Tipo de dado decimal

O tipo de dado decimal é usado para especificar um valor numérico.

O exemplo a seguir é uma declaração de decimal em um schema:

  <xs:element name="prize" type="xs:decimal"/>

Um elemento em seu documento poderia ser assim:

  <prize>999.50</prize>

Ou assim:

  <prize>+999.5450</prize>

Ou assim:

  <prize>-999.5230</prize>

Ou assim:

  <prize>0</prize>

Ou assim:

  <prize>14</prize>

Nota: O número máximo de dígitos decimais que você pode especificar é 18!

Tipo de dado integer

O tipo de dado integer é usado para especificar um valor numérico sem um componente fracionário.

O exemplo a seguir é uma declaração de um integer em um schema:

  <xs:element name="prize" type="xs:integer"/>

Um elemento em seu documento poderia ser assim:

  <prize>999</prize>

Ou assim:

  <prize>+999</prize>

Ou assim:

  <prize>-999</prize>

Ou assim:

  <prize>0</prize>

Tipos de dados numéricos

Note que todos os tipos de dados abaixo derivam do tipo de dado Decimal (exceto ele mesmo)!

Nome Descrição
byte Um inteiro 8-bit com sinal
decimal Um valor decimal
int Um inteiro 32-bit com sinal
integer Um valor inteiro
long Um inteiro 64-bit com sinal
negativeInteger Um inteiro contendo apenas valores negativos (..., -2, -1)
nonNegativeInteger Um inteiro contendo apenas valores não negativos (0, 1, 2, ...)
nonPositiveInteger Um inteiro contendo apenas valores não positivos (..., -2, -1, 0)
positiveInteger Um inteiro contendo apenas valores positivos (1, 2, ...)
short Um inteiro 16-bit com sinal
unsignedLong Um inteiro 64-bit sem sinal
unsignedInt Um inteiro 32-bit sem sinal
unsignedShort Um inteiro 16-bit sem sinal
unsignedByte Um inteiro 8-bit sem sinal

Restrições em tipos de dados numéricos

Restrições que podem ser usadas com tipos de dados numéricos:

  • enumeration
  • fractionDigits
  • maxExclusive
  • maxInclusive
  • minExclusive
  • minInclusive
  • pattern
  • totalDigits
  • whiteSpace

Tipos de dados variados

Outros tipos de dados variados são boolean, base64Binary, hexBinary, float, double, anyURI, QName, e NOTATION.

Tipo de dado boolean

O tipo de dado boolean é usado para especificar um valor true (verdadeiro) ou false (falso).

O exemplo a seguir é uma declaração de um boolean em um schema:

  <xs:attribute name="disabled" type="xs:boolean"/>

Um elemento em seu documento poderia ser asism:

  <prize disabled="true">999</prize>

Nota: Valores válidos para boolean são true, false, 1 (que indica true), e 0 (que indica false).

Tipos de dados binários

Tipos de dados binários são usados para expressar dados binários.

Nós temos dois tipos de dados binários:

  • base64Binary (dado binário codificado em Base64)
  • hexBinary (dado binário codificado em hexadecimal)

O exemplo a seguir é uma declaração de um hexBinary em um schema:

  <xs:element name="blobsrc" type="xs:hexBinary"/>

Tipo de dado anyURI

O tipo de dado anyURI é usado para especificar uma URI.

O exemplo a seguir é uma declaração de um anyURI em um schema:

  <xs:attribute name="src" type="xs:anyURI"/>

Um elemento em seu documento poderia ser assim:

  <pic src="http://www.w3schools.com/images/smiley.gif" />

Nota: Se uma URI tem espaços, substitua-os por %20.

Tipos de dados variados

Nome Descrição
anyURI
base64Binary
boolean
double
float
hexBinary
NOTATION
QName

Restrições em tipos de dados variados

Restrições que podem ser usados com outros tipos de dados:

  • enumeration (um tipo de dado Boolean não pode usar esta restrição)
  • length (um tipo de dado Boolean não pode usar esta restrição)
  • maxLength (um tipo de dado Boolean não pode usar esta restrição)
  • minLength (um tipo de dado Boolean não pode usar esta restrição)
  • pattern
  • whiteSpace

Referência de elementos XSD

Elementos XSD

Validador XSD

Validador XSD

Adicionar comentário

* Campos obrigatórios
5000
Powered by Commentics

Comentários

Nenhum comentário ainda. Seja o primeiro!


Veja a relação completa dos artigos de Maurício M. Maia