sexta-feira, 9 de março de 2012

XML SCHEMA - PARTE V

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!

Nenhum comentário:

Postar um comentário