Vamos comentar por partes as suas duvidas…
Uma coisa que acho que não está clara é a diferença entre nome do elemento e nome do tipo.
Veja esse schema:
<!-- Considerando que estamos trabalhando no namespace TESTE-NAMESPACE, prefixo "tns" -->
<element name="turma" type="tns:turma" />
<complexType name="turma">
<sequence>
<element name="professor" type="tns:pessoa" />
<element name="aluno" type="tns:pessoa" maxOccurs="30" />
</sequence>
</complexType>
<complexType name="pessoa">
<sequence>
<element name="nome" type="string" />
<element name="idade" type="int" />
</sequence>
</complexType>
E um xml válido:
<tns:turma>
<professor>
<nome>Professor Tavares</nome>
<idade>50</idade>
</professor>
<aluno>
<nome>Joaozinho</nome>
<idade>10</idade>
</aluno>
<aluno>
<nome>Maria</nome>
<idade>11</idade>
</aluno>
</tns:turma>
O elemento “turma” é do tipo “turma”. Os nomes do tipo e do elemento são iguais apenas por coincidencia, mas são coisas diferentes. Uma turma possui um professor e vários alunos.
Os elementos “professor” e “aluno” são do mesmo tipo, que é “pessoa”.
Uma pessoa possui um “nome”, do tipo String, e uma “idade”, do tipo int.
Vemos assim que o nome do elemento (no XSD) é o que vai dar nome à tag no XML, enquanto o tipo determina o que vai dentro dessa tag.
Fazendo uma comparação com Java, é como isso:
String valor = "teste"; // "valor" é o nome do elemento, String é o tipo
Cliente cliente = new Cliente(); // "cliente" é o nome, "Cliente" é o tipo. Por coincidencia são iguais
Quando se define o tipo diretamente no elemento, é criado um tipo anônimo, que é mais ou menos como um anonymous class do Java:
É um tipo que só vai ser usado para criar aquele elemento, nem tem nome porque garantimos que ele não será referenciado em nenhum outro lugar…
Runnable myRunnable = new Runnable() {
public void run() {
// faz algo...
}
};
O XSD anterior ficaria assim se fosse feito todo com tipos anônimos:
(Procure observar bem as diferenças e semelhanças em relação ao outro modo)
<element name="turma">
<complexType>
<sequence>
<element name="professor">
<complexType>
<sequence>
<element name="nome" type="string" />
<element name="idade" type="int" />
</sequence>
</complexType>
</element>
<element name="aluno" maxOccurs="30">
<complexType>
<sequence>
<element name="nome" type="string" />
<element name="idade" type="int" />
</sequence>
</complexType>
</element>
</sequence>
</complexType>
</element>
Isso tudo para chegar em um erro em um dos seus exemplos:
<element name="carro">
...
</element>
...
...
<extension base = "carro">
<element name = "nomeCarro" type = "string"/>
<element name = "montadora" type = "string"/>
</extension>
Não se pode criar uma extensão de “carro” porque ele não é um tipo!
Para usar a extensão (que é uma idéia parecida com a herança no java), seria necessário definir um tipo que represente um carro. Não dá para herdar de um tipo anônimo.
Seria como fazer:
Runnable myRunnable = new Runnable() {
public void run() {
// faz algo...
}
};
class RunnaFilha extends myRunnable {
// (!! NO NO NO !!)
}
Acredito que tenha ficado bem claro o conceito dos tipos. Insisti bastante nisso porque entendendo bem o resto fica fácil.
*** SimpleType
É um tipo que só possui como conteúdo um valor. Só isso. Não pode ter tags filhas, nem atributos.
São usados como tags apenas-texto ou como atributos de outras tags.
Os tipos “string”, “int”, “boolean”, e a maioria dos tipos pré-definidos, são simpleTypes.
- Mas porque criar um simpletype ao invés de usar um tipo pré-definido? Para ter maior controle sobre o conteúdo!
Um exemplo, no caso anterior ao invés de usar “int” para a idade, vamos criar um novo tipo:
<complexType name="pessoa">
<sequence>
<element name="nome" type="string" />
<element name="idade" type="tns:tipoIdade" />
</sequence>
</complexType>
<simpleType name="tipoIdade">
<restriction base="int">
<minInclusive value="0" />
<maxInclusive value="150" />
</restriction>
</simpleType>
*** ComplexType
Não há muito mais a acrescentar… são tipos que possuem tags filhas e/ou atributos. Como exemplo no caso anterior, temos “turma” e “pessoa”.
Seu conteúdo pode definido de uma das seguintes formas:
- Uma sequencia ou conjunto de tags filhas + atributos.
- Herança de um outro ComplexType
- Herança de um SimpleType
*** ComplexContent
Indica que o complexType que estamos definindo vai herdar de outro tipo complexo.
No XML existem dois tipos de herança, extension (quando se adiciona elementos ou atributos) ou restriction (quando se retira elementos ou atributos, ou ainda quando se restringe o valor para tipos simples).
A tag complexContent sempre vem seguida de ou
Poderiamos usar o seguinte exemplo, aproveitando o tipo “pessoa” definido anteriormente:
<element name="heroi" type="tns:pessoaComPoderes" />
<complexType name="pessoaComPoderes">
<complexContent>
<extension base="tns:pessoa">
<sequence>
<element name="poder" type="string" />
</sequence>
</extension>
</complexContent>
</complexType>
<heroi>
<nome>Superman</nome>
<idade>35</idade>
<poder>Voar + Superforça</poder>
</heroi>
*** SimpleContent
Indica que o complexType que estamos definindo vai herdar de um tipo simples (elemento apenas texto).
Quando herdamos de um tipo simples, só é possível restringir o valor e adicionar atributos.
Repare que tipos simples não possuem atributos, mas este é um tipo complexo criado a partir de um tipo simples. É um tipo complexo com “conteúdo simples”, quer dizer, apenas texto e sem tags filhas, porém pode ter atributos.
Exatamente como você fez no tipo da tag “estado” (só lembrando que “estado” não é o tipo, e sim o nome do elemento - o tipo é anônimo). Herdou de string, restringindo o valor, e adicionou o atributo regiao.
Ele deixa de ser um tipo simples pois agora possui um atributo, mas é um “tipo complexo com conteúdo simples”
Acho que é isso… sei la se expliquei direito rsrs
Gostaria de sugerir a leitura do seguinte tutorial:
http://www.w3schools.com/Schema/default.asp