Como implementar um DTD para XML

Neste artigo, veremos como se pode criar um DTD. A fim de compreender arquivos DTD XML (extensible markup language), vamos rever as noções básicas de XML neste introdução. Espera-se que você tenha um entendimento básico de XML, para este tutorial.

XML- A linguagem Extensible Markup Language (XML) é uma linguagem em texto puro, multi-plataforma, que permite que você armazene dados (como endereços em um catálogo de endereços) em uma forma estruturada. O documento XML deverá ter a sintaxe correta. Portanto, os documentos XML devem ser bem-formados quando forem feitos. Um documento bem-formado tem os seguintes elementos:

  • Tags fechadas (<hello> </ Olá> ou <hi />)
  • Um atributo de elemento deve estar entre aspas (<candy price="0.50">)
  • O XML diferencia maiúsculas e minúsculas. Em outras palavras, as tags de início e de fim devem ambas conter as mesmas letras em maiúsculo e em minúsculo.

Um exemplo muito simples de um documento XML é apresentado a seguir para o menu de uma confeitaria:

<candystore xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<candy>
<productName company="XYZ">Lollipops</productName>
<id>634847</id>
<price>0.50</price>
</candy>
<candy>
<productName company="ABC">Mints</productName>
<id>634812</id>
<price>0.75</price>
</candy>
</candystore>

A primeira sentença é a instrução de processamento. Ela diz ao analisador sintático que estamos trabalhando com uma versão particular de XML. O resto do documento é composto de nossas tags e elementos. No exemplo acima, o elemento "name" tem um atributo de "company". Uma ótima maneira de lembrar um atributo é pensar nele como uma propriedade que algo pode ter. Um doce tem um nome. O nome está associado a uma determinada empresa.

Em nosso tutorial, utilizaremos o exemplo acima e criaremos para ele uma DTD que vai definir regras sobre como o conteúdo de nosso elemento, ou dados em outras palavras, deve ser informado. (Por exemplo, o formato é esperado para nosso id? Pode ter caracteres alfabéticos?)

DTD (Document Type Definition)
- Uma DTD, como um Schema XML, declara metadados que atribuem um tipo particular, seja ele simples ou complexo, aos elementos e seus atributos em um documento XML.

  • Vamos dar uma olhada novamente em nosso exemplo para a confeitaria.

    <candystore xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <candy>
    <productName company="XYZ">Lollipops</productName>
    <id>634847</id>
    <price>0.50</price>
    </candy>
    <candy>
    <productName company="ABC">Mints</productName>
    <id>634812</id>
    <price>0.75</price>
    </candy>
    </candystore>

    Nosso elemento candystore tem dois sub-elementos. Cada elemento candy tem os subelementos do name, id, e price. Têm também um atributo chamado company. Ao construir as regras de sintaxe, temos de definir restrições para o formato de nossos dados. Estas restrições podem ser baseadas em como os dados serão utilizados. Se, por exemplo, o ID de nosso doce deve caber em 6 caracteres na fatura de um produto, então esta definição ajuda a determinar as nossas limitações. Faça a si mesmo a algumas perguntas sobre os seus dados:

    • Os dados têm de ser apenas números ou letras?
    • Os dados têm de ter um determinado comprimento? Ou, mais especificamente, um comprimento mínimo e/ou um máximo?
    • Os dados têm de ter um determinado atributo ou sub elemento especificado? Ou são opcionais?

    Agora que temos algumas idéias sobre o que podemos nos perguntar, podemos avançar. Vamos construir um conjunto de regras, antes de começar a criar o nosso código de Schema XML.

    • O nome do doce é obrigatório.
    • O nome da empresa não pode ser superior a 30 caracteres. É opcional.
    • O id deve ter todos os dígitos e deve ter exatamente o comprimento de 6 dígitos. É obrigatório.
    • O preço é obrigatório.
  • Com a nossa lista de regras, podemos agora criar nosso DTD (Data Type Definitio). Vamos revisar o básico.

    O melhor processo de pensamento de criação de um DTD é pensar em termos de criar uma tabela em um banco de dados. Do Passo 1, sabemos o que é necessário, desde o nome do doce até o preço. Com esta lista, podemos definir nossos elementos. Os elementos em um arquivo DTD são definidos da seguinte forma:

    <!ELEMENT elementname (content-type or content-model)>
    • elementname especifica o nome do elemento
    • Content-type or content-model especifica se o elemento contém dados de tipo texto, ou outros.

    Nosso elementos pode ser um dos três tipos: empty, unrestricted, ou container.

    Elementos empty não têm conteúdo (nome (texto) ou preço (numérico), etc) e são marcados como <empty-element/>.

    <!ELEMENTO storemanager EMPTY>

    Elementos unrestricted são naturalmente o oposto do elemento empty. Podem conter qualquer elemento declarado em algum outro lugar no arquivo DTD. Elementos container contêm dados no formato de caracteres e outros elementos.

    Antes de especificarmos nossos elementos, precisamos conhecer alguns símbolos utilizados em arquivos DTD:
    • ? - O elemento ocorre nenhuma ou uma vez.
    • , - Pode ser utilizado para especificar múltiplos filhos.
    • | - Este símbolo é usado como uma declaração OU. Este ou aquele valor valor é aceitável (qualquer dos valores apresentados).
    • + - Há um mínimo de uma ocorrência.
    • * - O elemento ocorre nenhuma ou mais vezes.

    <!ELEMENT productName (#PCDATA)>
    <!ELEMENT price (#PCDATA)>
    <!ELEMENT id (#PCDATA)>
    <!ELEMENT candystore ((candy+))>
    <!ELEMENT candy ((productName, id, price))>

    Após nossos elementos, temos o texto PCDATA, que basicamente significa um formato texto de dados. Nosso elemento candystore tem o elemento filho candy. Utilizamos o símbolo + porque podemos ter mais de um. O elemento candy tem os elementos filhos productName, id e price, que são contidos entre parêntesis depois de candy. Um de nossos elementos, productName, tem um atributo. Teremos de declarar esta situação, também.  

    <!ATTLIST elementname attributename valuetype [attributetype] [“default”]>

    A seção valuetype de attributename [attributetype] [ "default"] é repetida tantas vezes quanto necessário para criar vários atributos para um elemento.

    <!ATTLIST productName company CDATA #REQUIRED>
  • Agora, vamos construir o nosso arquivo DTD.
    A primeira coisa que precisamos em um arquivo DTD é uma instrução de processamento.
    <?xml version="1.0" encoding="UTF-8"?>
    A seguir, precisamos especificar o elemento ProductName e seus atributos.
    <!ELEMENT productName (#PCDATA)>
    <!ATTLIST productName company CDATA #REQUIRED>
    Agora, podemos especificar nossos outros elementos:
    <!ELEMENT price (#PCDATA)>
    <!ELEMENT id (#PCDATA)>
    A seguir vem nosso container candystore, com seu elemento filho candy::
    <!ELEMENT candystore ((candy+))>
    Finalmente, precisamos especificar o atributo de candystore. O atributo é, na realidade, alguma coisa que você poderia dispensar. Mas lembre-se, o XML espera que você siga a sintaxe. Retome a linha do elemento candystore no arquivo XML:
    <candystore xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    Precisamos definir isto como um atributo em nosso DTD:
    <!ATTLIST candystore
    xmlns:xsi CDATA #FIXED "http://www.w3.org/2001/XMLSchema-instance"
    >
    Por último, incluímos o elemento candy com seus atributos filhos:
    <!ELEMENT candy ((productName, id, price))> 
  • candystore.xml
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE candystore SYSTEM "candystore.dtd">
    <candy>

    <productName company="XYZ">Lollipops</productName>
    <id>634847</id>
    <price>0.50</price>
    </candy>
    <candy>
    <productName company="ABC">Mints</productName>
    <id>634812</id>
    <price>0.75</price>
    </candy>
    </candystore>
    candystore.dtd
    <?xml version="1.0" encoding="UTF-8"?>
    <!ELEMENT productName (#PCDATA)>
    <!ATTLIST productName company CDATA #REQUIRED>
    <!ELEMENT price (#PCDATA)>
    <!ELEMENT id (#PCDATA)>
    <!ELEMENT candystore ((candy+))>
    <!ATTLIST candystore
    xmlns:xsi CDATA #FIXED "http://www.w3.org/2001/XMLSchema-instance"
    >
    <!ELEMENT candy ((productName, id, price))>