15 de dezembro de 2010

Criando Esquema para validar um XML - parte III

A sintaxe para criação de esquemas XSD é bem mais flexível e poderosa do que os exemplos que mostrei no último post sobre esse assunto. Para tornar mais realista o exemplo da carga de produtos mostrado lá, podemos melhorá-lo agregando novas regras.

O defeito mais patente naquele exemplo é o fato de que apenas um produto por vez pode ser incluído no XML. Numa carga, faz mais sentido aceitar que se informem diversos itens de uma só vez. Como também não é permitido a um XML ter mais de um elemento como raiz, vou acrescentar uma nova raiz - produtos - e reconfigurar a tag de produto:
<xs:element name="produtos">
<xs:complexType>
<xs:sequence>
<xs:element name="produto" minOccurs="1" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="codigo" type="xs:string"/>
.
.
.
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>

Os atributos minOccurs e maxOccus aplicados ao elemento produto determinam as quantidades mínima e máxima que esse elemento pode aparecer no XML. Caso esses atributos sejam omitidos, eles assumem o valor 1 (um); por isso, omití-los obriga sempre uma ocorrência do elemento. Valores válidos para esses atributos são números inteiros mas no caso do maxOccus podemos informar ainda o texto "unbounded" para indicar que não há limite máximo de ocorrências para o elemento. O trecho de XSD acima exemplifica ainda elementos complexos aninhados uns dentro dos outros, isto é, eles não precisam ser formados apenas por elementos simples.

O minOccurs também aceita o valor 0 (zero), o que na prática significa que o elemento em questão poderá ser omitido do XML - e, ainda assim, ele permanecerá válido. Isso abre a possibilidade de atribuirmos valores padronizados para elementos que não apareçam no XML.
<xs:element name="saldo" type="xs:decimal" minOccurs="0" default="0"/>

No caso acima, se o elemento com o saldo do item não estiver presente no XML, devemos assumir que seu valor é zero.

Os tipos de dados com os quais definimos elementos no XSD constituem um tipo de restrição aos valores que esses elementos podem assumir no XML. No entanto, há situações em que só o tipo não é suficiente para determinar a validade de um dado. Para atender essa necessidade, um esquema XSD dispõe da tag xs:restriction, que, como o nome diz, serve para criar outras restrições aos valores permitidos em elementos simples num XML. A forma mais básica de restrição é a que estipula uma faixa de valores válidos:

<xs:element name="deposito" >
<xs:simpleType>
<xs:restriction base="xs:integer">
<xs:minInclusive value="1"/>
<xs:maxInclusive value="99"/>
</xs:restriction>
</xs:simpleType>
</xs:element>

O trecho acima reformula o elemento deposito para que ele aceite apenas códigos entre 1 e 99, sendo que esses valores-limites também são válidos. Repare que, apesar de continuar a ser um elemento simples (não são definidos elementos internos nele), o tipo do deposito agora foi passado para uma estrutura interna, delimitada por uma tag xs:simpleType, dentro da qual são explicitadas as novas restrições. Outros parâmetros válidos para configurar restrições podem ser encontrados neste link.

Outro tipo de restrição bastante comum é a lista de valores permitidos. Ou seja, para o XML ser válido, o valor do elemento nele tem que ser um daqueles listados na tag de restrição do XSD:
<xs:element name="unidade" maxOccurs="5">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:enumeration value="UN"/>
<xs:enumeration value="CX"/>
<xs:enumeration value="KG"/>
<xs:enumeration value="PC"/>
</xs:restriction>
</xs:simpleType>
</xs:element>

Como está exemplificado acima, cada item da lista de possíveis valores é definido através de uma tag xs:enumeration. Obviamente, os valores especificados na lista devem estar de acordo com o tipo base atribuído ao elemento - no caso apresentado acima, devem ser cadeias de caracteres (strings). Vale a pena ressaltar também que letras maiúsculas e minúsculas são consideradas diferentes e isso deve ser respeitado na hora de criar as declarações. Por exemplo, de acordo com os critérios do XSD acima, um valor un ou kg no elemento unidade do XML torna-o inválido visto que está prevista apenas a ocorrência desses valores em letras maiúsculas.

Alguns campos podem apresentar restrição de tamanho para serem válidos. No ERP da ABC71, por exemplo, a descrição de um produto deve ter no máximo 50 caracteres. Uma declaração para contemplar esse tipo de restrição pode ser feita como segue:
<xs:element name="descricao">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:minLength value="1"/>
<xs:maxLength value="50"/>
</xs:restriction>
</xs:simpleType>
</xs:element>

Além de maxLength e minLength - que definem uma faixa válida de quantidade de caracteres - há o elemento length, que serve para forçar uma quantidade exata de caracteres. Não a usei no exemplo porque isso obrigaria a colocar espaços em branco após as descrições de produto até que todos eles tivessem a quantidade exata exigida.

Há uma outra forma de restrição onde podemos estipular padrões de preenchimento dos campos, padrões estes baseados em máscaras mais ou menos como nas expressões regulares. Volto em outro post para falar sobre isso.

Mais Informações
Criando esquema para validar um xml - parte I e parte II, Elemento xs:restriction

Nenhum comentário :

Postar um comentário

OBS: Os comentários enviados a este Blog são submetidos a moderação. Por isso, eles serão publicados somente após aprovação.

Observação: somente um membro deste blog pode postar um comentário.