d`ilton moreira silveira mapeamento de dtds para...

101
D`Ilton Moreira Silveira Mapeamento de DTDs para Esquemas Lógico-Relacionais RELATÓRIO FINAL TCC Palmas – TO 2003

Upload: vokhuong

Post on 11-Jul-2018

217 views

Category:

Documents


0 download

TRANSCRIPT

D`Ilton Moreira Silveira

Mapeamento de DTDs para Esquemas Lógico-Relacionais

RELATÓRIO FINAL TCC

Palmas – TO 2003

D`Ilton Moreira Silveira

Mapeamento de DTDs para Esquemas Lógico-Relacionais

“Monografia apresentada como

requisito parcial da disciplina Prática de

Sistemas de Informação II (TCC) do

curso de Sistemas de Informação,

coordenada pela Profª. M.Sc. Deise de

Brum Saccol”

Palmas – TO 2003

D`ILTON MOREIRA SILVEIRA

Mapeamento de DTDs para Esquemas Lógico-Relacionais

“Monografia apresentada como

requisito parcial da disciplina Prática de

Sistemas de Informação II (TCC) do

curso de Sistemas de Informação,

coordenada pela Profª. M.Sc. Deise de

Brum Saccol”

Aprovado em dezembro de 2003.

BANCA EXAMINADORA

Profª. Deise de Brum Saccol, M.Sc.

Centro Universitário Luterano de Palmas

Prof°. Eduardo Kessler Piveta, M.Sc.

Centro Universitário Luterano de Palmas

Prof°. Fabiano Fagundes, M.Sc.

Centro Universitário Luterano de Palmas

AGRADECIMENTOS

Prezados leitores, alguns anos atrás eu tinha um sonho que por alguns motivos eu

pensava que não ia realizá-lo. Um certo dia me ligaram e deram-me uma notícia, eu estava

sendo chamado para fazer a minha matrícula na faculdade, nesse instante eu não sabia se o

meu sonho estava se tornado realidade ou em um pesadelo, pois eu não tinha dinheiro para

pagar a matriculo e muito menos as mensalidades. Eu, naquele instante tomei uma decisão,

peguei dinheiro emprestado para pagar a matrícula e me ingressar na vida acadêmica. E

graças a Deus, estou nesse momento escrevendo os agradecimentos do meu trabalho de

conclusão de curso universitário.

Agradeço primeiramente a Deus, que nunca me abandonou. E, nos momentos mais

difíceis da minha vida, Ele sempre tem me ajudado fazendo com que eu enxergue

caminhos que me levam a vitória. E graças a Ele eu estou concretizando um sonho dentre

vários outros que serão realizados.

Agradeço ao meu pai Neuton, posso dizer o melhor pai do mundo. Ele sempre está

ao meu lado pronto para me ajudar. Pai, te agradeço pelo senhor ter me ajudado a realizar

esse sonho. Agradeço também a minha mãe, Hilda. Mãe, obrigado pelas suas orações, e eu

digo que a senhora é a melhor mãe do mundo.

Agradeço aos meus irmãos, Denilton , Castilio, e Lucinéia, obrigado por fazerem

parte da minha vida.

Professor Fabiano, obrigado pelos momentos de distração no LABMIDIA, pelas

broncas nos momentos em que eu estava precisando, pelos incentivos, obrigado também

por ter me ajudado a escrever parte da minha história dentro da faculdade. Você é uma

pessoa especial que mora dentro do meu coração.

Professora Parcilene, obrigado pela tua amizade e pelo conhecimento que você me

proporcionou, sou muito grato a você. Que Deus possa vir te recompensar.

Professora Deise, a professora queridinha. Deise, foi muito bom trabalhar no

mesmo local que você, ser seu aluno, e é claro ser o seu orientando. Obrigado por fazer

parte de uma das minhas conquistas. Que a graça de Deus esteja sobre você.

Agradeço também a todos os demais professores, pela amizade, pelo conhecimento

a mim proporcionado. Que Deus possa vir recompensá-los.

Agradeço ainda as seguintes pessoa, Kênia, Polly, Elaine, Nábia, Suellen,

Anderson, Michael, Marcus, Danilo, Álvaro, Bruno. Vocês são pessoas especiais que

moram dentro do meu coração.

“O temor do Senhor é o princípio da sabedoria...”

Salmos 111:10a

SUMÁRIO

1. INTRODUÇÃO.......................................................................................... 13

2. REVISÃO DE LITERATURA ................................................................. 14

2.1 DADOS SEMI-ESTRUTURADOS E DADOS ESTRUTURADOS ........................ 14

2.2 EXTENSIBLE MARKUP LANGUAGE (XML) ............................................. 15

2.3 DOCUMENT TYPE DEFINITION (DTD) .................................................... 16

2.4 ARMAZENAMENTOS DE DOCUMENTOS XML.......................................... 19

2.5 USO DE SGBDS RELACIONAIS PARA O ARMAZENAMENTO DE XML........ 20

2.5.1 DB2.................................................................................................. 21

2.5.2 SQL Server 2000 .............................................................................. 22

2.5.3 Oracle 9i .......................................................................................... 22

2.6 GERAÇÃO DE ESQUEMA LÓGICO RELACIONAL A PARTIR DE DTD............. 23

2.6.1 Primeira abordagem ........................................................................ 23

2.6.2 Segunda abordagem ......................................................................... 25

2.6.3 Terceira abordagem ......................................................................... 27

2.6.4 Quarta abordagem ........................................................................... 32

3. MATERIAIS E MÉTODOS...................................................................... 35

4. RESULTADOS E DISCUSSÕES.............................................................. 36

4.1 PROPOSTA............................................................................................. 36

4.2 ESTUDO DE CASO .................................................................................. 37

4.3 REPRESENTAÇÃO DA DTD EM FORMATO XML ...................................... 42

4.4 ALGORITMO DE GERAÇÃO DE ESQUEMAS LÓGICOS A PARTIR DA DTD ..... 43

4.4.1 Elementos PCDATA ......................................................................... 44

4.4.2 Elemento complexo........................................................................... 47

4.4.3 Elemento vazio ................................................................................. 50

4.4.4 Elemento misto ................................................................................. 52

4.5 SISTEMA IMPLEMENTADO ...................................................................... 56

4.6 COMPARAÇÃO ENTRE OS ALGORITMOS APRESENTADOS NA REVISÃO DE

LITERATURA E O ALGORITMO DESENVOLVIDO NESSE TRABALHO ............. 58

5. CONSIDERAÇÕES FINAIS E TRABALHOS FUTUROS..................... 61

6. REFERÊNCIAS BIBLIOGRÁFICAS ..................................................... 63

Lista de Abreviaturas

DTD Document Type Definition

SGBD Sistema Gerenciador de Banco de Dados

SQL Structured Query Language

SGML Standard Generalized Markup Language

XML extensible Markup Language

W3C World Wide Web Consortium

Lista de Figuras

FIGURA 1 – EXEMPLO DE UM DOCUMENTO XML.............................................................. 16

FIGURA 2 - EXEMPLO DE UMA DTD QUE VALIDA O DOCUMENTO XML DA FIGURA 1 ......... 18

FIGURA 3 – DTD EXEMPLO PARA AS ABORDAGENS DE MAPEAMENTO. .............................. 24

FIGURA 4 – ESQUEMA LÓGICO RELACIONAL GERADO SEGUNDO A DTD DA FIGURA 3

(ABORDAGEM 1) ....................................................................................................... 25

FIGURA 5 – GRAFO DA DTD DA FIGURA 3 (SEGUNDA ABORDAGEM) ................................. 26

FIGURA 6 – ESQUEMA LÓGICO RELACIONAL GERADO SEGUNDO A DTD DA FIGURA 3

(ABORDAGEM 2). ...................................................................................................... 27

FIGURA 7 – REGRAS PARA ELIMINAR A COMPLEXIDADE DOS DTDS (LU ET AL 2003). ....... 28

FIGURA 8 – ALGORITMO INLINING (LU ET AL 2003).......................................................... 29

FIGURA 9 – GRÁFICO INLINING DA DTD (LU ET AL 2003) ................................................ 30

FIGURA 10 – GRAFO INLINING DA DTD DA FIGURA 3 ........................................................ 30

FIGURA 11 – ESQUEMA LÓGICO RELACIONAL GERADO SEGUNDO A DTD DA FIGURA 3

(ABORDAGEM 3) ....................................................................................................... 32

FIGURA 12 – DOCUMENTO XML VÁLIDO SEGUNDO A DTD DA FIGURA 3.......................... 33

FIGURA 13 – GRAFO DO DOCUMENTO XML DA FIGURA 12 ............................................... 33

FIGURA 14 – ARQUITETURA DO SISTEMA ......................................................................... 36

FIGURA 15 – DTD PARA PUBLICAÇÕES DE LIVROS E ARTIGOS ........................................... 38

FIGURA 16 – DOCUMENTO XML VÁLIDO SEGUNDO A DTD DA FIGURA 15 – EXEMPLO 01 . 39

FIGURA 17 – DOCUMENTO XML VÁLIDO SEGUNDO A DTD DA FIGURA 15 – EXEMPLO 02 . 40

FIGURA 18 – DOCUMENTO XML VÁLIDO SEGUNDO A DTD DA FIGURA 15 – EXEMPLO 03 . 41

FIGURA 19 – DTD MSG ................................................................................................... 42

FIGURA 20 – REPRESENTAÇÃO XML DA DTD DA FIGURA 19 ........................................... 43

FIGURA 21 – INICIO DO ALGORITMO................................................................................. 44

FIGURA 22 – PARTE DO ALGORITMO QUE TRATA DE ELEMENTO PCDATA E MONOVALORADO.

................................................................................................................................ 45

FIGURA 23 – PARTE DO ALGORITMO QUE TRATA DE ELEMENTO PCDATA E MULTIVALORADO.

................................................................................................................................ 46

FIGURA 24 – PARTE DO ALGORITMO QUE TRATA DE ELEMENTO FILHO MULTIVALORADO E

ELEMENTO PAI MULTIVALORADO OU ELEMENTO FILHO MONOVALORADO E ELEMENTO PAI

MULTIVALORADO. ...................................................................................................... 48

FIGURA 25 – PARTE DO ALGORITMO QUE TRATA DE ELEMENTO FILHO MULTIVALORADO E

ELEMENTO PAI MONOVALORADO. ................................................................................. 49

FIGURA 26 – PARTE DO ALGORITMO QUE TRATA DE ELEMENTO FILHO MONOVALORADO E

ELEMENTO PAI MONOVALORADO. ................................................................................. 49

FIGURA 27 – PARTE DO ALGORITMO QUE TRATA DE ELEMENTO VAZIO. .............................. 51

FIGURA 28 – INICIO DO ALGORITMO QUE TRATA DE ELEMENTO MISTO................................ 53

FIGURA 29 – PARTE DO ALGORITMO QUE TRATA DE ELEMENTO MISTO – QUANDO O FILHO

DO ELEMENTO MISTO É PCDATA. .............................................................................. 53

FIGURA 30 – PARTE DO ALGORITMO QUE TRATA DE ELEMENTO MISTO – QUANDO O FILHO

DO ELEMENTO MISTO POSSUI FILHOS. ...................................................................... 54

FIGURA 31 – PARTE DO ALGORITMO QUE TRATA DE ELEMENTO MISTO – QUANDO O FILHO

DO ELEMENTO MISTO FOR UM PCDATA. ................................................................... 55

FIGURA 32 – PARTE DO ALGORITMO QUE TRATA DE ELEMENTO MISTO – QUANDO O FILHO

DO ELEMENTO MISTO FOR UM ELEMENTO VAZIO......................................................... 56

FIGURA 33 – INTERFACE DO SISTEMA............................................................................... 57

FIGURA 34 – MODELO LÓGICO RELACIONAL GERADO A PARTIR DA DTD DA FIGURA 3. ..... 58

Lista de Tabelas

TABELA 1 – EXEMPLO TABELA BASEADO EM ARCO – COM BASE NO GRAFO DA FIGURA 13.. 34

TABELA 2 – TAUTOR – MAPEAMENTO COM INLINING ....................................................... 34

TABELA 3 – TNOME – MAPEAMENTO COM INLINING.......................................................... 34

RESUMO

Esse trabalho busca definir um algoritmo capaz de mapear uma DTD (Document

Type Definition) para um modelo lógico relacional. Após a definição desse

algoritmo, implementá-lo em uma linguagem de programação, desenvolvendo

assim, uma ferramenta que gerará um script SQL do modelo lógico relacional, o

qual poderá ser executado, como por exemplo, no SQL Server.

ABSTRACT

This work aims to define an algorithm to map a DTD (Document type definition) to

a relational logical model. After the definition of this algorithm, to implement it in a

programming language. In this way, a tool will be developed to generate a SQL script,

which can be executed over SQL Server, for instance.

13

1. INTRODUÇÃO

Sistemas Gerenciadores de Banco de Dados (SGBDs) específicos para documentos

XML (extensible Markup Language) ainda estão em fase de amadurecimento e são

relativamente pouco utilizados, principalmente devido ao pequeno número de produtos

comerciais disponíveis. Atualmente, para o armazenamento de documentos XML, SGBDs

relacionais têm sido mais usados. Para isso, faz-se necessário um mapeamento de

documentos XML para o modelo relacional. Várias abordagens têm sido utilizadas neste

mapeamento, dentre elas, a criação de esquemas lógicos relacionais a partir de DTDs.

Nesse trabalho foi desenvolvido um algoritmo capaz de realizar o mapeamento de

DTDs para modelos lógico relacionais, e uma aplicação que gera um script SQL

(Structured Query Language), tendo como base o algoritmo proposto nesse trabalho. Uma

vez que se tenha o script SQL gerado pela aplicação, o usuário pode executá-lo no SQL

Server (SGBD utilizado neste trabalho), criando um banco de dados com todas as tabelas

definidas no script, assim como os relacionamentos entre elas.

Atualmente, existem várias abordagens sobre algoritmos que fazem o mapeamento

de DTDs para um modelo lógico relacional. Dentre eles, pode-se citar as seguintes

referências: (BOU 2001), (SHA 99) e (LU et al 2003).

O trabalho está organizado da seguinte forma: o capítulo 2 apresenta a revisão de

literatura que está subdividida em: Dados Semi-Estruturados e Dados Estruturados; uma

descrição sobre XML; DTDs; uma demonstração de armazenamento de documentos XML;

uma abordagem sobre o uso de SGBDs relacionais para o armazenamento de documentos

XML; e também são apresentados alguns algoritmos que realizam o mapeamento de DTDs

para modelo lógico relacional. No capítulo 3 têm-se os materiais e métodos. O capítulo 4

relata os resultados e discussões. E o 5 mostra as considerações finais e os trabalhos

futuros.

14

2. REVISÃO DE LITERATURA

Este capítulo apresenta uma abordagem sobre dados semi-estruturados e

estruturados, XML, DTD, armazenamento de documentos XML, o uso de SGBDs

Relacionais para o armazenamento de XML e por fim sobre geração de esquemas lógicos

relacionais a partir de DTDs.

2.1 Dados Semi-estruturados e Dados Estruturados

Atualmente, têm-se muitas informações disponíveis em sistemas eletrônicos. Essas

informações encontram-se em diversos formatos, como textos, imagens, tabelas etc. Neste

trabalho são citados dois formatos de dados: semi-estruturados e estruturados.

Para dados semi-estruturados têm-se um exemplo clássico que são os dados da

Web, como bibliotecas digitais, sites de comércio eletrônico etc. Este tipo de dado

geralmente não possui um esquema associado no momento de sua criação.

Dados semi-estruturados apresentam as seguintes características (MELLO et al,

2000):

• Definição de esquema a posteriori: esquemas de dados são criados após a

existência dos dados;

• Estrutura irregular: os dados estão organizados de formas diferentes;

• Estrutura implícita: mesmo existindo uma estrutura para os dados, “essa

estrutura está implícita na forma como os dados são apresentados. É

necessário realizar uma computação para obter essa estrutura”;

• Estrutura parcial: apenas parte dos dados seguem uma estrutura;

• Estrutura extensa: “a ordem de magnitude de uma estrutura para estes dados

é grande, uma vez que os mesmos são muito heterogêneos. Supondo

diferentes formatos para um curriculum vitae, uma união de atributos

significativos em cada formato pode produzir um esquema extenso”;

15

• Estrutura evolucionária: há uma modificação constante tanto da estrutura

dos dados quanto dos seus valores;

• Estrutura descritiva e não prescritiva: “dada a natureza irregular e

evolucionária dos dados semi-estruturados, as estruturas de representação

implícitas ou explícitas normalmente se restringem a descrever o estado

corrente de poucas ocorrências de dados similares. Desta forma, não é

possível prescrever esquemas fechados e muitas restrições de integridade

com relação à semântica dos atributos. Um sinônimo para estrutura

descritiva é estrutura indicativa”;

• Distinção entre estrutura e dados não é clara: a estrutura depende da

descrição dos dados, tornando a distinção entre estrutura e valor confusa.

Ao contrário de dados semi-estruturados, os dados estruturados possuem um

esquema definido no momento de sua criação; têm-se como exemplo de dados estruturados

os modelos de dados relacionais, orientados a objetos etc.

Dados estruturados possuem as seguintes características (MELLO et al, 2000):

• Esquema pré-definido: esquemas de dados são definidos antes da existência

dos dados;

• Esquema independente dos dados: a estrutura dos dados não depende dos

dados para existir;

• Estrutura reduzida: a estrutura não vária dentro de um mesmo esquema;

• Fracamente evolutiva: não sofre mudanças em sua estrutura freqüentemente;

• Distinção entre estrutura e dados: a estrutura não depende da descrição dos

dados, tornando a distinção lógica entre estrutura e valor clara;

No próximo tópico têm-se uma breve abordagem sobre XML, uma linguagem de

representação de dados.

2.2 eXtensible Markup Language (XML)

Documentos XML seguem uma estrutura hierárquica, podendo ser divididos em

tags iniciais, tags finais, elementos, atributos etc. Um documento XML pode ser validado

segundo uma DTD. Elementos são representados por tags (<resp></resp>) e cada

elemento pode possuir atributos, elementos e textos. Na figura 1 têm-se um exemplo de um

16

documento XML.

<?xml version='1.0' encoding = "ISO-8859-1"?> <!DOCTYPE listacompra SYSTEM "listacompra.dtd"> <listacompra>

<resp><nome>Kênia</nome>

</resp><local>

<nome>Quarteto</nome></local><compra>

<data dia="12" mes="8" ano="2002"/></compra><setor>

<nome>frios</nome><produto>

<quant>2</quant><unid>kg</unid><nome>queijo</nome><precoant>9.00</precoant><precoat>10.00</precoat>

</produto></setor>

</listacompra>

Figura 1 – Exemplo de um documento XML

A estrutura tem como elemento raiz listacompra, sendo que ele possui vários

elementos filhos. O primeiro é resp e é composto por nome que possui como conteúdo

Kênia. O segundo é local que possui um filho nome com um conteúdo Quarteto. O

próximo filho é o elemento compra, o qual possui um elemento data constituído de três

atributos com seus respectivos valores. E por fim, o elemento setor constituído por dois

elementos filhos, nome e produto.

No próximo tópico têm-se uma breve abordagem sobre DTD.

2.3 Document Type Definition (DTD)

DTDs são utilizadas para descrever a estrutura de documentos XML e podem ser

consideradas esquemas para estes documentos. Para isso, utiliza-se de regras de sintaxe e

de palavras-chaves. A estrutura de uma DTD está dividida em elementos e atributos

(ANDERSON 2001).

17

Elementos são declarados em uma DTD através da tag ELEMENT, sendo que o

conteúdo de um elemento pode ser vazio, outros elementos, misto ou qualquer. Possui

também dois elementos de ordem que são: “,” (seqüência estrita) e “|” (escolha). Para

um elemento, define-se também a sua cardinalidade, operadores que especificam quantas

vezes um elemento pode se repetir em um documento XML. Os operadores podem ser:

“?” (opcional), “*” (zero ou mais vezes) ou “+” (uma ou mais vezes) (ANDERSON

2001).

Conteúdos de um elemento (ANDERSON 2001):

• Elemento vazio: são elementos que não possuem elementos filhos e nem

texto; elementos vazios podem ter atributos e são definidos pela palavra-

chave EMPTY;

• Elemento: a definição do elemento só possui elementos filhos e não contém

texto;

• Elemento misto: é uma mistura de #PCDATA (texto) e elementos;

• Elemento qualquer: é um elemento de conteúdo aberto a qualquer conteúdo

que não viole a sintaxe do XML bem-formado; éb definido pela palavra-

chave ANY.

Atributos complementam e modificam elementos, oferecendo meios de associar

propriedades simples a elementos (ANDERSON 2001). Os atributos de um elemento são

declarados dentro de uma tag ATTLIST seguida pelo nome do elemento.

Existem quatro definições padrões para atributos que são (ANDERSON 2001):

• #REQUIRED: o atributo é obrigatório em cada instância do elemento;

• #IMPLIED: o atributo é opcional em cada instância do elemento;

• #FIXED mais valor padrão: o atributo sempre tem o valor padrão mesmo

não aparecendo no documento;

• Somente valor padrão: se o atributo não aparecer, o valor padrão é

presumido pelo parser. Se o atributo aparecer, pode ter outro valor.

Atributos podem ser dos seguintes tipos (ANDERSON 2001):

• CDATA: string;

• ID: permite um único valor em todo o documento;

• IDREF: Referência a algum elemento que tenha um atributo ID existente no

documento;

18

• IDREFS: Referência a mais de um elemento que tenha um atributo ID

existente no documento;

• ENTITY: nome de uma entidade pré-definida;

• ENTITIES: série de ENTITY;

• NMTOKEN: uma declaração NMTOKEN fica em aberto podendo ser

alterado em qualquer ponto da DTD, ou seja, receber outro valor em outro

elemento;

• NMTOKENS: uma série de NMTOKEN;

• NOTATION: aceita um ou uma série de nomes indicando tipo de anotações

declarados na DTD;

• Valor enumerado: uma série de valores definidos pelo usuário com

finalidade de explicitar os valores possíveis de serem aceitos.

<!ELEMENT listacompra (resp*,local*,compra,setor+,email)><!ELEMENT resp (nome)><!ATTLIST resp id ID #REQUIRED><!ELEMENT nome (#PCDATA)><!ELEMENT local (nome)><!ELEMENT compra (data)><!ELEMENT data EMPTY><!ATTLIST data dia CDATA #REQUIRED

mes (1|2|3|4|5|6|7|8|9|10|12) "1"ano NMTOKENS #REQUIRED>

<!ELEMENT setor (nome,produto+)><!ATTLIST setor id_resp IDREF #REQUIRED><!ELEMENT produto (quant,unid,nome,precoant,precoat)><!ELEMENT quant (#PCDATA)><!ELEMENT unid (#PCDATA)><!ELEMENT precoant (#PCDATA)><!ELEMENT precoat (#PCDATA)><!ELEMENT email EMPTY><!ATTLIST email usuario CDATA #REQUIRED

dominio NOTATION (ulbra-to.br|bol.com.br|yahoo.com.br)"ulbra-to.br">

<!ENTITY site "lista.txt">

Figura 2 - Exemplo de uma DTD que valida o documento XML da figura 1

O exemplo de um elemento pode ser visto em listacompra, que é um

elemento raiz, o qual possui uma lista de elementos que são: resp* (o asterístico “*”

indica a cardinalidade do elemento, ou seja, esse elemento pode repetir zero ou mais vezes

em um mesmo documento), local*, compra, setor+ (o sinal de “+” também indica

19

a cardinalidade do elemento, ou seja, esse elemento pode ocorrer uma ou mais vezes em

um mesmo documento) e o elemento email.

Para exemplificar a definição de um atributo têm-se os atributos dos elementos

data, resp, setor e email. O elemento data é um elemento vazio (definido

pela palavra-chave EMPTY) e possui três atributos que são: dia, do tipo CDATA e é

obrigatório (definido como REQUIRED); mes, definido com uma lista de valores e valor

padrão “1”; e ano, do tipo NMTOKENS. O elemento resp possui um atributo id do ID

e é obrigatório. O elemento setor possui o atributo id_resp do tipo IDREF e também

é obrigatório. Para o elemento email existem dois atributos; um deles (dominio) é do

tipo NOTATION. Para exemplificar uma entidade têm-se a declaração da entidade site.

2.4 Armazenamentos de Documentos XML

Para o armazenamento e posterior acesso a documentos XML, pode-se utilizar

quatro abordagens principais (FLO, 99).

A primeira seria a utilização de repositórios de dados nativos, como por exemplo,

Rufus (SHO, 93), Lore (McH, 97), Tamino (SOFTWARE AG, 1999) e Strudel (FER, 98).

Esses são sistemas voltados especificamente para o armazenamento de documentos XML,

sendo que os mesmos seguem uma estrutura própria para trabalhar com índices, otimização

de consultas etc.

A segunda abordagem é a utilização de um banco de dados orientado a objetos.

Nessa abordagem, são exploradas as técnicas de modelagem orientadas a objetos.

Atualmente, são encontrados alguns sistemas comerciais que suportam essa abordagem,

como, por exemplo, O2 ou Objectsore (CHR 94), e o projeto Monet (ZWO 99).

A terceira abordagem é a utilização de bancos de dados relacionais. Armazenar

documentos XML em um banco de dados relacional implica, primeiramente, em definir o

esquema lógico deste banco. Assim, torna-se necessário realizar o mapeamento entre o

modelo de dados semi-estruturados e o esquema lógico relacional. Os dados XML são

mapeados para tabelas em um modelo relacional; as consultas submetidas aos dados semi-

estruturados são mapeadas para SQL.

A última abordagem é armazenar os documentos XML em arquivos texto. Arquivos

são formados por uma estrutura hierárquica, sendo que, essa estrutura é composta por tags

20

iniciais e tags finais (elementos), atributos, valores de atributos e conteúdo de elementos.

Algumas considerações sobre as abordagens apresentadas (FLO, 99):

Os sistemas nativos deveriam apresentar-se como a melhor alternativa, uma vez que

são construídos especificamente para o armazenamento deste tipo de documento. Como

ainda estão em fase de desenvolvimento, apresentam-se pouco escaláveis.

O mesmo acontece com base de dados orientada a objetos. Ainda estão em fase de

maturidade e tendem a apresentar queda de performance no acesso a bases de dados muito

grandes.

Já os sistemas de bancos de dados relacionais são sistemas maduros e trabalham

bem com uma escala grande de dados. Permitem trabalhar com dados extraídos de

documentos XML e dados tradicionais (estruturados). Além disso, pode ser aproveitada a

SQL na manipulação dos dados.

2.5 Uso de SGBDs relacionais para o armazenamento de XML

Bases de dados relacionais apresentam um esquema pré-definido e uma estrutura

homogênea a nível de atributos e tipos (MELLO et al, 2000). Já para dados semi-

estruturados, ocorre a heterogeneidade para cada ocorrência de dados tanto a nível de

atributos quanto de tipos. “Dada essa heterogeneidade, em geral a estrutura de um dado

semi-estruturado está presente na própria descrição do dado, necessitando ser identificada e

extraída. Estas tarefas são complexas, uma vez que a distinção entre esquema e dados nem

sempre é clara, se compararmos ocorrências de dados semanticamente iguais” (MELLO et

al, 2000).

Sistemas de bases de dados relacionais têm-se apresentado como uma das

abordagens mais utilizadas atualmente para o armazenamento de dados XML. São sistemas

maduros, apresentam uma boa escalabilidade, são encontrados muitos produtos comerciais

disponíveis, é uma tecnologia bastante conhecida, além do uso de SQL com processadores

de consultas bem otimizados.

“SQL é a linguagem padrão para se lidar com bancos de dados relacionais, e é

aceita por quase todos os produtos existentes no mercado” (DATE, 2000).

As operações básicas realizadas por SQL são:

• INSERT: permite inserir dados em tabelas da base de dados

21

o Exemplo: INSERT INTO <tabela> [<campos>] [VALUES

<valores>]

• UPDATE: permite atualizar dados em tabelas da base de dados

o Exemplo: UPDATE <tabela> SET <campo> =

<expressão> [WHERE <condição>]

• DELETE: permite deletar dados em tabelas da base de dados;

o Exemplo: DELETE FROM <tabela> [WHERE <condição>]

• SELECT: permite selecionar dados em tabelas da base de dados.

o Exemplo: SELECT * FROM [<nome da tabela>] WHERE

[<condição>]

Para utilizar sistemas de bases de dados relacionais para o armazenamento de

XML, tem se a necessidade de fazer o mapeamento de dados XML para o modelo de dados

relacional. No tópico 2.6 serão apresentadas algumas abordagens sobre esses

mapeamentos.

A seguir, são apresentados três SGBDs e algumas funcionalidades para o

armazenamento de XML.

2.5.1 DB2

O DB2 é um SGBD relacional desenvolvido pela IBM (DB2 2003a). A partir da

segunda versão passou a suportar o armazenamento e manipulação de objetos complexos,

acoplando as características comuns do DB2 Universal Database (DB2 UDB) à

extensibilidade da XML (DB2 2003b).

Para trabalhar com XML, utiliza-se o DB2 XML Extender. Essa ferramenta permite

trabalhar com dois meios de armazenamento de documentos XML (DB2 2003a). O

primeiro é armazenar o documento XML inteiro, sem modificações, em uma coluna da

base de dados (XML column). O segundo permite fazer uma decomposição do documento

XML, armazenando os dados extraídos em tabelas relacionais (XML collection).

Abaixo são apresentados algumas das funcionalidades oferecidas pelo DB2 XML

Extender (DB2 2003c):

• Armazenamento, recuperação e atualizações dos dados XML em uma única

coluna;

22

• Facilita o levantamento de informações para soluções de business-to-

business e e-business através de formato XML-based;

• Extração de elementos e atributos em tipos de dados tradicionais SQL,

(sistema de indexação e funcionalidades de SQL query para DB2);

• Armazena documentos XML como uma coleção de dados DB2, em

múltiplas colunas e em tabelas.

2.5.2 SQL Server 2000

É um produto da Microsoft que trabalha com modelo de dados relacional e suporta

aplicações Cliente/Servidor. A partir do SQL Server 2000, a Microsoft disponibilizou

suporte para trabalhar com XML, permitindo importar e exportar dados XML, formas de

adaptação entre dados XML e dados relacionais etc (SERVER 2000b).

As principais funções de manipulação oferecidas pelo SQL Server 2000 para

trabalhar com dados XML (SERVER 2000a) são:

• OpenXML: fornece visões relacionais de dados XML; podem ser usadas

para consultas a dados XML e junção de dados XML com tabelas

relacionais existentes;

• FOR XML: fornece acesso a dados XML existentes em uma base de dados

relacional, com a utilização de SELECT e de palavras-chaves de OPenXML

T/SQL.

Com o SQL Server 2000, os usuários podem realizar consultas e retornar o

resultado em formato XML, fazer combinações de dados de tabelas relacionais com dados

originados de documentos XML, mapear múltiplas tabelas em uma junção com atributos e

elementos específicos de documentos XML etc (SERVER 2000a).

2.5.3 Oracle 9i

O Oracle é um SGBD relacional desenvolvido pela Oracle Corporation. Suporta

três tipos de armazenamento de documentos XML (ORACLE 2002):

• Tipo de dados Char: é um campo string. Nesse caso, os dados são

armazenados em uma tabela do banco de dados como uma única cadeia de

23

caracteres. Uma das maiores dificuldades na utilização desse tipo de

armazenamento é a lentidão no processamento de consultas aos dados, pois

o conteúdo dos dados pode ser muito extenso;

• Tipo de dados CLOB: nesse tipo de armazenamento, o documento XML

fica armazenado em um grande arquivo texto na base de dados e há um

ponteiro no campo da tabela para esse documento. Uma das maiores

dificuldades de se trabalhar com esse tipo de dados é que o documento só

pode ser recuperado por completo;

• Tipo de dados XMLType: esse tipo de dados armazena o documento XML

como é feito com o tipo CLOB, mas com o auxílio de métodos que vêm

acoplados a ele permite criar, extrair e indexar os dados contidos no

documento e recuperar tags específicas com a utilização de XPath. Algumas

funções do XMLType: CreateXML(); ExistsNode(); Extract() etc.

2.6 Geração de esquema lógico relacional a partir de DTD

DTDs são utilizadas como esquemas para documentos XML. Através de DTDs,

pode-se prever o que existirá em um documento XML e o que o documento pode conter,

com a definição de elementos e atributos ligados aos elementos.

Há na literatura várias abordagens para o mapeamento de uma DTD para um

esquema lógico relacional. Algumas destas abordagens são apresentadas a seguir.

2.6.1 Primeira abordagem

A primeira destas abordagens é definida da seguinte forma (BOU 2001):

• Para cada elemento complexo, cria-se uma tabela e uma coluna de chave

primária;

• Para cada elemento com conteúdo misto, cria-se uma tabela separada para

armazenar o PCDATA, ligando à tabela pai através da chave primária da

tabela pai;

• Para cada atributo monovalorado de um elemento e para cada elemento

filho simples de ocorrência única, cria-se uma coluna na tabela do elemento.

24

Se o elemento ou atributo do elemento for opcional, a coluna também é

opcional;

• Para cada atributo multivalorado e para cada elemento filho simples de

múltipla ocorrência, cria-se uma tabela separada para armazenar os valores,

ligada à tabela pai através da chave primária da tabela pai;

• Para cada elemento filho complexo, liga-se a tabela do elemento pai à tabela

do elemento filho com a chave primária da tabela pai.

Na figura 4 têm-se o exemplo do funcionamento desse processo. Para esse exemplo

têm-se a DTD da figura 3:

<!ELEMENT artigo(autor,titulo_artigo,resumo,secao*,bibliografia)><!ELEMENT autor (nome,instituicao?,endereco?)><!ELEMENT nome (#PCDATA)><!ELEMENT instituicao (#PCDATA)><!ELEMENT endereco (#PCDATA)><!ELEMENT secao (paragrafo|figura)+><!ELEMENT paragrafo (#PCDATA)><!ELEMENT figura EMPTY><!ATTLIST figura tipo NOTATION (gif|jpg) "gif"

nome CDATA "figura1"><!ATTLIST artigo data CDATA #REQUIRED

ultima_revisao CDATA #REQUIREDversao CDATA #IMPLIED>

<!ATTLIST secao titulo CDATA #REQUIREDnumero ID #REQUIRED>

<!ELEMENT bibliografia (referencia+)><!ELEMENT referencia (obra,autor+,ano?,local?)><!ATTLIST referencia id ID #REQUIRED><!ELEMENT obra (#PCDATA)><!ELEMENT ano (#PCDATA)><!ELEMENT local (#PCDATA)><!ELEMENT titulo_artigo (#PCDATA)><!ELEMENT resumo (#PCDATA|paragrafo)*>

Figura 3 – DTD exemplo para as abordagens de mapeamento.

Seguindo os passos citados anteriormente, têm-se o seguinte esquema lógico

relacional da figura 4.

25

Tb_artigo(id,id_autor,titulo_artigo,id_resumo,id_bibliografia,data,ultima_revisao,versao)Tb_autor(id,nome,instituicao,endereco)Tb_resumo(id)Tb_pcdata(id,id_resumo,pcdata)Tb_paragrafo_resumo(id,id_resumo,paragrafo)Tb_secao_artigo(id_artigo,id_secao)Tb_secao(id,numero)Tb_paragrafo(id,paragrafo)Tb_paragrafo_secao(id_paragrafo,id_secao)Tb_figura(id,tipo,nome)Tb_figura_secao(id_figura,id_secao)Tb_bibliografia(id)Tb_referencia(id,id_bibliografia,obra,ano,local)Tb_autor_referencia(id_autor,id_referencia)

Figura 4 – Esquema lógico relacional gerado segundo a DTD da figura 3 (abordagem 1)

Notação: na representação do modelo relacional as chaves primárias estão definidas

em negrito e sublinhadas; as chaves primárias e estrangeiras estão em negrito, sublinhadas

e em itálico; as chaves estrangeiras estão em itálico.

2.6.2 Segunda abordagem

Um dos problemas em se mapear DTDs para esquemas lógicos relacionais é a

grande fragmentação do documento, como pode ser visto no exemplo anterior. A segunda

abordagem visa diminuir essa fragmentação. Abaixo, têm-se os principais pontos que são

tratados na segunda (SHA 99):

• A complexidade permitida na declaração de elementos, a cardinalidade dos

elementos (opcional, obrigatório e multivalorado), elemento filho, elemento

raiz etc;

• Os conflitos de mapeamento entre o esquema relacional (atributos e tabelas)

e o aninhamento arbitrário de elementos na DTD;

• Os atributos multivalorados e a recursão entre elementos.

Abaixo seguem as transformações necessárias para tratar os pontos citados acima

(SHA 99):

1. Transformações de nivelamento: converter uma definição aninhada em uma

representação plana. Por exemplo:

� (a,b)* é transformado em a*,b*

26

� (a,b)? é transformado em a?,b?

� (a|b) é transformado em a?,b?

2. Transformações de simplificação: reduzir vários operadores unários em um

único. Por exemplo:

� a** é transformado em a*

� a*? é transformado em a*

� a?* é transformado em a*

� a?? é transformado em a?

3. Transformações de agrupamentos: agrupar sub-elementos que possuem o

mesmo nome. Por exemplo:

� ...,a*,...,a*,... é transformado em a*,...

� ...,a*,...,a?,... é transformado em a*,...

� ...,a?,...,a*,... é transformado em a*,...

� ...,a?,...,a?,... é transformado em a*,...

� ...,a,...,a,... é transformado em a*,...

4. Transformação de operadores + em *;

Um elemento definido como (SACCOL 2001):

<!ELEMENT a ((b|c|e)?(e?|(f?,(b,b)*))*)>

é transformado em: <!ELEMENT a (b*,c?,e*,f*)>.

Após a simplificação da DTD, gera-se um grafo simplificado, o qual servirá como

base para gerar o modelo lógico relacional. Abaixo têm-se um exemplo de um grafo.

Figura 5 – Grafo da DTD da figura 3 (segunda abordagem)

27

Cria-se tabelas para todos os elementos da DTD que não possuem nó apontando

para ele (artigo). Elementos que são apontados por mais de um nó geram tabelas

quando são recursivos. Todos os elementos apontados por * geram tabelas separadas.

“Elementos apontados por um único nó são agrupados nas tabelas já existentes. Na

existência de elementos mutuamente recursivos e alcançáveis por um único nó, um deles

deve gerar uma tabela separada. Os outros elementos existentes devem ser agrupados nas

tabelas existentes” (SACCOL 2001).

Abaixo têm-se o esquema lógico relacional da DTD da figura 3 gerado a partir da

abordagem citada acima.

Tb_artigo(id,nome,instituicao,endereco,ultima_revisao,data,versoa,titulo_artigo,id_resumo,id_bibliografia)Tb_resumo(id)Tb_pcdata(id,id_resumo,pcdata)Tb_paragrafo(id,paragrafo)Tb_resumo_paragrafo(id_resumo,id_paragrafo)Tb_secao(id,id_artigo,numero)Tb_secao_paragrafo(id_secao,id_paragrafo)Tb_figura(id,id_secao,tipo,nome)Tb_bibliografia(id)Tb_referencia(id,id_bibliografia,local,ano,obra)Tb_autor(id,id_referencia,nome,instituicao,endereco)

Figura 6 – Esquema lógico relacional gerado segundo a DTD da figura 3 (abordagem 2).

2.6.3 Terceira abordagem

Segundo (LU et al 2003): Elementos XML e atributos são modelados como

elementos. Uma DTD D é modelada como um conjunto de elementos XML {d1, d2,

..., dk}. Cada elemento XML di (i=1, ..., k) é da forma ni=ei, onde ni é o

nome do elemento XML e ei é a expressão da DTD.

Cada expressão da DTD é composta de nomes de elementos XML (expressões

primitivas) e outras subexpressões DTD com os seguintes operadores: , * + ? |

Uma expressão DTD e é definida recursivamente na seguinte notação BNF, onde n

varia sobre os nomes de elementos XML e e1, ..., em sobre as expressões DTD.

Essa abordagem contém três etapas, que são (LU et al 2003):

• Eliminação da complexidade das DTDs;

28

• Criação e inlining de grafos DTD;

• Geração de um esquema relacional.

A figura 6 mostra as regras utilizadas para eliminar a complexidade das DTDs.

1.e+�e*2.e?�e3.(e1|···|en)�(e1,···,en)4.(a)(e1,···,en)*�(e1*,···,en*)

(b) e**�e*5.(a) ···,e, ···,e, ···�···,e*,···,···

(b) ···,e, ···,e*,···�···,e*,···,···(c) ···,e*,···,e,···�···,e*,···,···(d) ···,e*,···,e*,···�···,e*,···,···

Figura 7 – Regras para eliminar a complexidade dos DTDs (LU et al 2003).

Regra 1. Aplicando a regra 1 o DTD resutante não conterá +.

Regra 2. Aplicando a regra 2 o DTD resultante não conterá ?.

Regra 3. Aplicando a regra 3 o DTD resultante não conterá |.

Regra 4(a) e 4(b). Aplicando as regras 4 (a) e 4(b) o DTD resultante fica

da seguinte forma: (e1,e2,...,en). Cada ei =e ou e* (i=1,...,n), onde e é o

nome do elemento.

Regra 5(a), 5(b), 5(c) e 5(d). Aplicando essas regras o DTD resultante

fica da seguinte forma: (e1,e2,...,en). Sendo que, cada ei contém um nome distinto

do elemento.

Aplicando as regras citadas acima nesse DTD (LU et al 2003): <ELEMENT a

((b+,c*,d?)?,(e?,f,(g*,h?)+)?)> o seu DTD resultante é: <ELEMENT a

(b*,c*,d,e,f,g*,h*)>.

Segundo (LU et al 2003) as regras para eliminar a complexidade dos DTDs

apresentadas acima sofreram algumas melhorias em relação às regras apresentadas por

(SHA 99):

• Completude: Considera todas as combinações possíveis dos operadores e

elementos XML. Como por exemplo, (e1|···|en)?. Essa condição não é

tratada por (SHA 99);

• Eficiência: O algoritmo garante que as regras sejam aplicadas de acordo

com a ordem apresentada na figura 7, reduzindo o número de regras a serem

29

aplicadas a cada passo;

• Simplificação extra: Eliminar o “?” simplifica o grafo resultante da DTD.

Na etapa de criação e inlining do grafo da DTD, cria-se o grafo correspondente à

DTD simplificada. No grafo, cada nó representa um elemento de XML e cada arco

representa um operador de “,” ou “*”. O procedimento inlining considera três casos

(LU et al 2003):

• Caso 1: O elemento a é conectado a b por a, e b não tem nenhum outro

arco chegando a ele. Em outras palavras b não é um nó compartilhado;

• Caso 2: O elemento a é conectado a b por a, mas b contém outros arcos

chegando a ele. Ou seja b é um nó compartilhado;

• Case 3: O elemento a é conectado a b por a. Nesse caso, cada a contém

ocorrências múltiplas do elemento b.

Abaixo têm-se o algoritmo apresentado por (LU et al 2003):

Algorithm Inline(DTDGraph G)Begin

For each node e in G doIf not visited(e)then

InlineNode(e)End If

End ForEndAlgorithm InlineNode(Node e)Begin

Mark e as “visited”For each child c of e do

If not visited(c)thenInlineNode(c)

End IfEnd ForFor each child c of e do

If inlinable(c)thene.inlinedSet ∪=c.inlinedSet;assign all children of c as thechildrenof eAndthendeletecfromG

End IfEnd For

End

Figura 8 – Algoritmo inlining (LU et al 2003)

O algoritmo inlining pode ser executado em O(n) onde n é o número dos elementos

30

na DTD da entrada.

Abaixo são mostrados os grafos inlining da DTD (LU et al 2003):

Figura 9 – Gráfico inlining da DTD (LU et al 2003)

Usando o procedimento inlining da figura 8, o grafo da DTD mostrado na figura

9.A será inlined no grafo mostrado na figura 9.B, e o grafo da DTD mostrado na figura 9.C

será inlined no grafo mostrado na figura 9.D.

Após aplicar o algoritmo, observa-se que um grafo da DTD tem as seguintes

propriedades: os nós são conectados por um arco ‘,’ ou ‘*’ e um arco ‘,’ deve apontar para

um nó compartilhado (LU et al 2003). Abaixo tem se o grafo inlining da DTD da figura 3.

Figura 10 – Grafo inlining da DTD da figura 3

31

Depois do grafo simplificado da DTD, a última etapa é gerar um esquema

relacional baseado neste grafo. O esquema relacional gerado suporta operações como

insert, select, delete e update de um elemento arbitrário de XML declarado na entrada da

DTD (LU et al 2003).

Gerando o esquema lógico relacional (LU et al 2003):

1. Para cada nó e uma relação e é gerada com os seguintes atributos

relacionais.

o O ID é a chave primária, e para cada atributo XML A de e, um

atributo relacional correspondente ao atributo A é criado com o

mesmo nome;

o If | e.inilinedSet | >=2, introduz-se o nodetype do

atributo para indicar o tipo do elemento XML a ser armazenado em

uma tupla;

o O nome de todo elemento XML terminal em e.inilinedSet.

Uma vez que um elemento não terminal é armazenado com valores

de ID e nodetype, e o armazenamento de sub-elementos contidos

nele, nenhum atributo adicional é necessário;

o Se houver um arco de e para o nó c, introduz-se c.ID como uma

chave estrangeira em e referenciando a relação c.

2. Se houver ao menos duas relações t1(ID) e t2(ID) geradas pelo item

1, então combina-se todas as relações da forma t(ID) em uma única

relação table1(ID,nodetype), sendo que o nodetype indica qual

elemento XML é armazenado em uma tupla;

3. Se houver ao menos duas relações t1(ID,t1) e t2(ID,t2) geradas

no item 1, então combina-se toda as relações da forma t(ID,t) em uma

única relação table2(ID,nodetype,pcdata), sendo que o

nodetype indica qual elemento XML é armazenado em uma tupla;

4. Se houver ao menos um arco * no grafo inlined da DTD, introduz-se uma

relação edge(parentID,childID,parentType,childType)

para armazenar todos os relacionamentos parent-child

32

correspondentes a arcos *.

Aplicando esta abordagem à DTD da figura 3, têm-se o seguinte esquema gerado:

Tb_artigo(id,id_autor,ultima_revisao,data,versao,id_resumo,id_bibliografia)Tb_autor(id,nome_autor,instituicao,endereco)Tb_resumo(id)Tb_pcdata(id,id_resumo,pcdata)Tb_paragrafo(id,paragrafo)Tb_resumo_paragrafo(id_resumo,id_paragrafo)Tb_secao(id,id_artigo,numero)Tb_secao_paragrafo(id_secao,id_paragrafo)Tb_figura(id,tipo,nome)Tb_secao_figura(id_secao,id_figura)Tb_bibliografia(id)Tb_referencia(id,id_bibliografia,local,ano,obra)Tb_referencai_autor(id_referencia,id_autor)

Figura 11 – Esquema lógico relacional gerado segundo a DTD da figura 3 (abordagem 3)

2.6.4 Quarta abordagem

A abordagem proposta por (FLO 99) define um esquema relacional a partir de um

grafo resultante de um documento XML. Neste grafo, nos modelam objetos, arcos

modelam atributos do objeto (rótulos) e folhas contém valores de dados (cadeias de

caracteres).

Essa abordagem é dividida em duas categorias: mapeamento de atributos e

mapeamento de valores.

O mapeamento de atributos pode ser feito de 4 formas distintas: armazenar todos os

atributos em uma única tabela (abordagem dos arcos); agrupar todos os atributos com o

mesmo nome em uma mesma tabela (abordagem dos atributos); armazenar todos os

atributos em uma mesma tabela, mas com nomes de colunas diferentes para cada atributo

(tabela universal); armazenar atributos multivalorados em tabelas separadas (abordagem

universal normalizada).

A figura 12 mostra um documento XML válido segundo a DTD da figura 3

33

<?xml version='1.0'?><!DOCTYPE artigo SYSTEM "artigo.dtd"><artigo ultima_revisao="2001" data="10/02/2001">

<autor><nome>D`ilton</nome>

</autor><titulo_artigo>XML</titulo_artigo><resumo>

resumo 1<paragrafo>Paragrafo 1</paragrafo>

</resumo><bibliografia>

<referencia id="ref1"><obra>obra 1</obra><autor>

<nome>D`ilton</nome></autor>

</referencia></bibliografia>

</artigo>

Figura 12 – Documento XML válido segundo a DTD da figura 3

A figura 13 mostra e representação em forma de grafo do documento XML da

figura 12.

Figura 13 – Grafo do documento XML da figura 12

Com base no grafo da figura 13, têm-se abaixo a tabela gerada seguindo o

mapeamento de atributos – abordagem dos arcos.

34

Tabela 1 – Exemplo tabela baseado em arco – com base no grafo da figura 13 Origem Ordem Nome Destino

R 1 artigo 1

1 1 ultima_revissao 2001

1 2 data 10/20/2001

1 3 autor 2

2 1 nome D`ilton

O mapeamento de valores pode ser feito de duas formas (FLO 99): tabelas

separadas de valores (uma tabela para cada tipo de dados) e mapeamento Inlining (valores

e atributos nas mesmas tabelas).

Na tabela 2 têm-se uma representação do mapeamento Inlining, tendo como base o

grafo da figura 13.

Tabela 2 – Tautor – mapeamento com Inlining Tautor

Origem Ordem Val_int Val_string Destino

1 3 Null Null 2

Tabela 3 – Tnome – mapeamento com Inlining

Tnome

Origem Ordem Val_int Val_string Destino

2 1 Null D`ilton null

Maiores detalhes destas abordagens podem ser encontradas em (FLO 99).

35

3. MATERIAIS E MÉTODOS

O trabalho foi desenvolvido no Laboratório de Multimídia (LABMIDIA) do

CEULP/ULBRA – Palmas – TO.

A ferramenta de desenvolvimento utilizada foi o Delphi 7. Foi utilizado também o

compilador javacc e o j2sdk para a utilização do DTDParser.jj (Parser utilizado para gerar

a representação da DTD em XML).

Seguiu-se a seguinte metodologia: primeiro definiu-se uma DTD para validar os

documentos XML gerados pelo DTDParser. A partir desta DTD, utilizou-se o componente

XML Data Binding (Delphi) para gerar uma interface que acessa os documento XML

gerados pelo DTDParser. Em seguida, foi implementado o algoritmo proposto nesse

trabalho, o qual gera um script.sql, sendo que esse script é a representação da DTD em um

modelo relacional.

36

4. RESULTADOS E DISCUSSÕES

Este capítulo apresenta a proposta para o mapeamento de DTDs para um modelo

lógico relacional. Também são mostrados o estudo de caso utilizado, a representação da

DTD em formato XML e o algoritmo proposto para o mapeamento.

No tópico abaixo têm-se a proposta de desenvolvimento desse trabalho.

4.1 Proposta

Esse trabalho visa desenvolver um algoritmo para o mapeamento de DTDs para um

modelo lógico relacional e também a sua implementação. Primeiramente, será feita uma

representação da DTD em um formato XML através de um Parser javacc. Após, será

realizado o mapeamento da DTD através do aplicativo que gerará um script.sql com o

modelo lógico relacional da DTD para o SQL Sever. Para entender melhor a proposta desse

trabalho é apresentada na figura 14 a arquitetura do sistema proposto.

Figura 14 – Arquitetura do Sistema

37

A arquitetura do sistema está dividida da seguinte forma:

1. DTD.dtd: entra-se no sistema com uma DTD válida;

2. JavaCC: nesse módulo do sistema utiliza-se de um parser, gerado por uma

gramática com ações semánticas DTDparser.jj, que valida uma DTD

(JAVACC 2003). Esse DTDparser.jj foi modificado de forma a gerar uma

representação XML de uma DTD;

3. DTD.XML: é o documento XML gerado pelo parser do módulo JavaCC, o

qual será utilizado para gerar os script.sql através do aplicativo;

4. XML Data Binding (Delphi): este é um componente do Delphi que

a partir de uma DTD gera uma interface que permite acessar qualquer

documento XML válido segundo esta DTD. Essa interface é utilizada para

fazer a leitura do DTD.XML, possibilitando a implementação do algoritmo

proposto neste trabalho;

5. script.sql: modelo lógico relacional gerado com a utilização do

algoritmo proposto nesse trabalho;

6. SGBD SQL Server: SGBD utilizado para executar os comandos SQL de

criação de tabelas.

4.2 Estudo de caso

DTDs são utilizadas para definir uma estrutura para documentos XML. Nessa

seção, têm-se exemplos de utilização de DTD e de documentos XML válidos segundo uma

DTD. A DTD utilizada para o exemplo tem sua definição voltada para publicações de

artigos e livros. Um artigo pode ter um título, autor, bibliografia etc. Um

livro pode ter um título, autores, bibliografia, capítulo, seção etc. A

próxima figura mostra a DTD definida para publicações.

38

<!ELEMENT publicacoes (livro|artigo)+><!ELEMENT livro(titulo,(autores|autor),editora?,capitulos?,secao*,bibliografia?)><!ATTLIST livro data CDATA #IMPLIED

ultima_revisao CDATA #IMPLIEDversao CDATA #IMPLIED cod ID #REQUIREDedicao CDATA #IMPLIED >

<!ELEMENT autores (autor*)><!ELEMENT autor (#PCDATA|nome)*><!ELEMENT nome (#PCDATA)><!ELEMENT editora (#PCDATA)><!ELEMENT capitulos (capitulo+)><!ELEMENT capitulo (#PCDATA | referencia | paragrafo)*><!ATTLIST capitulo titulo CDATA #REQUIRED

numero ID #REQUIRED ><!ELEMENT referencia EMPTY><!ATTLIST referencia cod IDREF #REQUIRED ><!ELEMENT paragrafo (#PCDATA | referencia)*><!ELEMENT secao (paragrafo | figura)+><!ATTLIST secao titulo CDATA #REQUIRED

numero (s1 | s3) #REQUIRED ><!ELEMENT bibliografia (ref+)><!ELEMENT ref (obra, autor)><!ATTLIST ref id ID #REQUIRED ><!ELEMENT obra (#PCDATA)><!ELEMENT figura EMPTY><!ATTLIST figura tipo CDATA #REQUIRED

nome (figura1.gif | figura2.gif) #REQUIRED ><!ELEMENT artigo (titulo,autor+,bibliografia?)><!ELEMENT titulo (#PCDATA)>

Figura 15 – DTD para publicações de livros e artigos

Para a DTD da figura 15 foram definidos três documentos XML. Na figura 16 têm-

se o primeiro documento XML válido segundo a DTD da figura 15.

39

<?xml version="1.0"?><!DOCTYPE publicacoes SYSTEM "publicacoes.dtd"><publicacoes>

<livro data="05/09/2000" ultima_revisao="10/01/2001"cod="l1"><titulo>XML</titulo><autor>D`ilton</autor><editora>Ciência Moderna</editora><capitulos>

<capitulo titulo="Introducao" numero="n1">Texto teste...<paragrafo>Paragrafo teste 1</paragrafo>

</capitulo></capitulos><bibliografia>

<ref id="f1"><obra>XML</obra><autor>

<nome>Deise</nome></autor>

</ref></bibliografia>

</livro></publicacoes>

Figura 16 – Documento XML válido segundo a DTD da figura 15 – exemplo 01

Para esse primeiro documento XML (figura 16) foi armazenado somente um

livro, o qual está composto por titulo, autor, editora, capitulos e

paragrafo. A figura 17 mostra o segundo documento XML válido conforme a DTD da

figura 15.

40

<?xml version="1.0"?><!DOCTYPE publicacoes SYSTEM "publicacoes.dtd"><publicacoes>

<artigo><titulo>IonoSoft</titulo><autor>

<nome>D`ilton</nome><nome>Washington Luiz Carvalho Lima</nome>Piveta

</autor><bibliografia>

<ref id="f3"><obra>Ionosfera</obra><autor>

<nome>Washington</nome></autor>

</ref></bibliografia>

</artigo><livro data="05/09/2000" ultima_revisao="10/01/2001"cod="l1">

<titulo>XML</titulo><autor>D`ilton</autor><editora>Ceiencia Moderna</editora><capitulos>

<capitulo titulo="Introducao" numero="n1">Texto teste...<paragrafo>Paragrafo teste 1</paragrafo>

</capitulo></capitulos><bibliografia>

<ref id="f1"><obra>XML</obra><autor>

<nome>Deise</nome></autor>

</ref></bibliografia>

</livro></publicacoes>

Figura 17 – Documento XML válido segundo a DTD da figura 15 – exemplo 02

O documento XML da figura 17 possui um artigo e um livro, sendo composto por

titulo, autor e bibliografia. O livro possui titulo, autor, editora,

capitulos e paragrafo. Como pode ser visto, os documentos da figura 16 e 17 são

válidos segundo a mesma DTD e possuem estruturas diferentes. A figura 18 mostra outro

exemplo de um documento XML válido segundo a DTD da figura 15.

41

<?xml version="1.0"?><!DOCTYPE publicacoes SYSTEM "publicacoes.dtd"><publicacoes>

<artigo><titulo>IonoSoft</titulo><autor>

<nome>D`ilton</nome><nome>Washington Luiz Carvalho Lima</nome>Piveta

</autor><bibliografia>

<ref id="f3"><obra>Ionosfera</obra><autor>

<nome>Washington</nome></autor>

</ref></bibliografia>

</artigo><livro data="05/09/2000" ultima_revisao="10/01/2001"cod="l1">

<titulo>XML</titulo><autor>D`ilton</autor><editora>Ceiencia Moderna</editora><capitulos>

<capitulo titulo="Introducao" numero="n1">Texto teste...<paragrafo>Paragrafo teste 1</paragrafo>

</capitulo></capitulos><bibliografia>

<ref id="f1"><obra>XML</obra><autor>

<nome>Deise</nome></autor>

</ref></bibliografia>

</livro><artigo>

<titulo>Mapeamento de DTDS</titulo><autor>D`ilton</autor><bibliografia>

<ref id="f1"><obra>DataBase DTDs</obra><autor>

<nome>D`ilton</nome></autor>

</ref></bibliografia>

</artigo></publicacoes>

Figura 18 – Documento XML válido segundo a DTD da figura 15 – exemplo 03

42

Para validar os documentos XML da figura 16, 17 e 18 foi utilizada a mesma DTD.

Como pode ser visto, todos os documentos possuem estruturas diferentes, sendo que estas

estruturas estão previstas na DTD. Ao se mapear essa DTD para um modelo lógico

relacional, deve-se levar em conta a cardinalidade dos elementos, flexibilidade do

documento, atributos e garantir que todos os dados sejam representados no modelo lógico

relacional.

4.3 Representação da DTD em formato XML

Para facilitar o mapeamento da DTD para um modelo lógico relacional, essa DTD

será representada em formato XML, através de um analisador sintático e léxico.

O analisador léxico (AHO et al, 1995) tem como função principal ler os caracteres

de entrada e produzir uma seqüência de tokens que o parser utiliza para a análise sintática.

O analisador sintático (AHO et al,1995) “obtém uma cadeia de tokens proveniente

do analisador léxico, e verifica se ela pode ser gerada pela gramática da linguagem-fonte”.

O analisador sintático relata todos os erros de sintaxe, como por exemplo (AHO et

al,1995):

• Léxicos: grafia errada de um identificador, palavras-chaves ou operador;

• Sintático: uma expressão aritmética com parênteses não-balanceados;

• Semânticos: um operador aplicado a um operando incompatível;

• Lógicos: uma chamada infinitamente recursiva.

Um exemplo de um analisador sintático e léxico é o Java Compiler-Compiler

(JavaCC) (JAVACC 2000). Para mapear a DTD para um formato XML será utilizado um

parser DTDParser (DTDParser 2001) compilado pelo JavaCC. Esse parser recebe em sua

entrada uma DTD e após, validá-la, gera em sua saída um documento XML representando

a DTD. Segue em anexo o DTDParser.

Para melhor entender a representação de uma DTD em um formato XML será

apresentada na figura 19 uma DTD e na figura 20 a sua representação em XML.

<!ELEMENT msg (de,para*,conteudo)><!ELEMENT de (#PCDATA)><!ELEMENT para (#PCDATA)><!ELEMENT conteudo (#PCDATA)>

Figura 19 – DTD msg O DTDParser faz um mapeamento de todos os elementos, atributos, cardinalidades,

43

montando um documento XML como o mostrado na figura 20.

<dtd><elemento>

<pai><filho><nome>de</nome></filho><filho><nome>para</nome></filho><filho><nome>conteudo</nome></filho><nome>msg</nome>

</pai></elemento><elemento>

<pai><pcdata>PCDATA</pcdata><nome>de</nome>

</pai></elemento><elemento>

<pai><pcdata>PCDATA</pcdata><nome>para</nome>

</pai></elemento><elemento>

<pai><pcdata>PCDATA</pcdata><nome>conteudo</nome>

</pai></elemento>

</dtd>

Figura 20 – Representação XML da DTD da figura 19

A figura 20 mostra a representação XML da DTD da figura 19. O documento XML

tem como elemento raiz <DTD> e para armazenar o elemento raiz e seus filhos definidos

na DTD têm-se a tag <Elemento> e dentro da mesma tem a tag <pai> e dentro dela

zero ou várias tags <filho> com seu respectivo nome, zero ou uma tag <pcdata> e a

tag <nome>, que é o nome do elemento raiz.

No próximo tópico têm-se a apresentação do algoritmo desenvolvido nesse

trabalho.

4.4 Algoritmo de geração de esquemas lógicos a partir da DTD

Nessa seção será apresentado o algoritmo desenvolvido nesse trabalho. Para

44

melhor compreensão do algoritmo, ele será divido por tipos de elementos como:

elemento PCDATA, elemento complexo, elemento vazio e elemento

misto. A figura 19 mostra o início do algoritmo.

iniciopara cada elemento da DTD{

se o elemento for raiz{gera uma tabela;cria um coluna chave primaria para esta tabela;se possui atributos{

addAtributosElemento(pai);}para cada filho do elemento{...}

}}

Figura 21 – Inicio do algoritmo

Como mostra a figura 21, primeiramente verifica-se o elemento raiz da DTD e cria-

se uma tabela com uma chave primária para esse elemento. Após, verifica-se se o mesmo

possui atributos; sendo verdade, adiciona-se os tributos do elemento em sua tabela através

do procedure addAtributosElemento(filho). Em seguida, verifica-se todos

os seus elementos filhos. Nas próximas seções têm-se um comentário sobre cada tipo de

elemento filho descrevendo, o seu mapeamento para o modelo relacional.

4.4.1 Elementos PCDATA

Para elemento PCDATA são consideradas duas categorias: os elementos

monovalorados (para esses elementos são considerados os elementos que podem

existir ou não no documento XML) e os elementos multivalorados.

No primeiro caso, os elementos são mapeados para a tabela do pai, caso não possua

atributos. Possuindo atributos e somente um pai, é armazenado na tabela do pai juntamente

com seus atributos. Possuindo atributos e mais de um pai, gera-se uma tabela para o

elemento com seus respectivos atributos e gera-se também uma tabela auxiliar

referenciando a tabela do pai e a tabela do filho.

Para o segundo caso, elementos multivalorados, gera-se uma tabela para o elemento

filho referenciando a tabela do pai, caso não possua atributos. Possuindo atributos e

somente um pai, gera-se uma tabela para o elemento com seus respectivos atributos e uma

45

referência à tabela do pai. Caso possua atributos e mais de um pai, gera-se uma tabela para

o filho com seus respectivos atributos e gera-se também uma tabela auxiliar referenciando

a tabela do elemento filho e a tabela de seu pai.

Na figura 22 é tratada a primeira abordagem.

se for PCDATA e monovalorado{senão possui atributos{

adiciona uma coluna para este elemento na tabela pai;}senão{

se possui somente um pai{adiciona uma coluna para este elemento na tabelapai;addAtributosElementoPcdata(pai,filho,modifier,cont_pai);

}senão{gera uma tabela para o filho com uma coluna chaveprimaria e uma coluna para o elemento filho;adiciona o id do filho na tabela pai;addAtributosElementoPcdata(pai,filho,modifier,cont_pai);}

}}

Figura 22 – Parte do algoritmo que trata de elemento PCDATA e monovalorado.

A figura 22 mostra o mapeamento de elemento PCDATA e monovalorado para

um modelo relacional. Primeiramente, verifica-se se o elemento possui atributos; caso o

elemento não possua atributos, cria-se uma coluna para o elemento na tabela pai, sendo que

também é levado em conta se o elemento é opcional ou obrigatório. Se o elemento possui

atributos são levadas em conta duas condições: verificar se o elemento possui somente um

pai ou mais de um pai.

Acontecendo do elemento possuir somente um pai, adiciona-se na tabela pai uma

coluna para o elemento filho, e através do procedure

addAtributosElementoPcdata(pai,filho,modifier,cont_pai)

adiciona-se os atributos do elemento filho na tabela pai.

O elemento, possuindo mais de um pai, é definido uma tabela para o filho, sendo

adicionado nessa tabela uma chave primária, uma coluna para o elemento e seus atributos

através do procedure

addAtributosElementoPcdata(pai,filho,modifier,cont_pai). Para as

duas condições acima é levado em conta se o elemento é obrigatório ou opcional.

46

A figura 23 descreve a segunda abordagem dessa seção.

se for PCDATA e multivalorado{senão possui atributos{

gera uma tabela com o nome do filho junto ao nome dopai, uma coluna chave estrangeira referenciando atabela do pai e uma coluna para o elemento filho;

}senão{se possui somente um pai{

gera uma tabela para o filho com uma coluna chaveprimaria, uma coluna chave estrangeirareferenciando a tabela do pai e uma coluna para oelemento filho;addAtributosElementoPcdata(pai,filho, ,modifier,cont_pai);

}senão{gera uma tabela para o filho com uma coluna chavePrimaria e uma coluna para o elemento filho;gera uma tabela auxiliar com duas colunas chavesestrangeiras, uma que referencia a tabela dofilhoe a outra a tabela pai;addAtributosElementoPcdata(pai,filho,modifier,cont_pai);}

}}

Figura 23 – Parte do algoritmo que trata de elemento PCDATA e multivalorado.

A figura 23 descreve o mapeamento de um elemento PCDATA e

Multivalorado para um modelo relacional. Como a abordagem anterior, verifica-se se

o elemento possui atributos; caso o elemento possua atributos, é gerada uma tabela com o

nome do filho junto ao nome do pai (tb_filho_pai) com suas respectivas colunas

(chave primária, chave estrangeira que referencia a tabela pai e uma coluna para o

elemento). Para os elementos que possuem atributos são levadas em conta duas condições:

a primeira, elementos que possuem somente um pai, e a segunda, elementos que possuem

mais de um pai.

Para a primeira condição, cria-se uma tabela para o filho com duas chaves (uma

primária e outra estrangeira referenciando a tabela pai), uma coluna para o elemento filho e

por fim adiciona à tabela os seus atributos. Na segunda condição, cria-se uma tabela para o

filho e uma tabela auxiliar que faz a ligação entre a tabela do filho e a tabela do pai. Na

próxima seção têm-se uma abordagem sobre o mapeamento de elementos

complexos para um modelo relacional.

47

4.4.2 Elemento complexo

Os elementos complexos foram divididos nas seguintes categorias:

• Elemento filho multivalorado e elemento pai

multivalorado. No caso de possuir somente um pai, gera-se uma tabela

para o filho com seus respectivos atributos, caso existam, e uma referência a

tabela do pai. Possuindo mais de um pai, gera-se uma tabela para o filho

com seus respectivos atributos, caso existam, e gera-se também uma tabela

auxiliar referenciando a tabela do filho e a tabela do pai;

• Elemento filho monovalorado e elemento pai

multivalorado. Faz-se o mesmo mapeamento da primeira categoria;

• Elemento filho multivalorado e elemento pai

monovalorado. Faz-se o mesmo mapeamento da primeira categoria;

• Elemento filho monovalorado e elemento pai

monovalorado. Nesse caso verifica-se se após o parêntese existe o

símbolo “*” ou “+”. Existindo esse símbolos e o elemento possuindo

somente um pai, gera-se uma tabela para o filho com seus atributos, caso

possua, e cria uma referência com a tabela do pai. Possuindo mais de um

pai, gera-se uma tabela para o filho com seus respectivos atributos e gera-se

também uma tabela auxiliar referenciando a tabela do pai. Ocorrendo de não

possuir os símbolos citados acima e também não possuindo somente filhos

multivalorados adiciona-se na tabela do pai uma referência à tabela do filho.

Caso possua somente filhos multivalorados, cria-se uma tabela para o pai

com seus respectivos atributos, caso os possua, e uma referência à tabela do

pai.

Para elemento filho multivalorado e elemento pai

multivalorado ou elemento filho monovalorado e elemento pai

multivalorado têm-se a figura 24.

48

se o (filho for multivalorado e pai multivalorado) ou (filho for

monovalorado e o pai multivalorado){se possui somente um pai{

gera uma tabela para o filho com uma coluna chaveprimaria e uma coluna chave estrangeira que referenciaa tabela pai;se possui atributos{addAtributosElemento(filho);}

}senão{gera uma tabela para o filho com uma coluna chaveprimaria;gera uma tabela auxiliar com duas colunas chavesestrangeiras, uma que referencia a tabela do filho eoutra a tabela do pai;se possui atributos{addAtributosElemento(filho);}

}}

Figura 24 – Parte do algoritmo que trata de elemento filho multivalorado e elemento pai multivalorado ou elemento filho monovalorado e elemento pai multivalorado.

A figura 24 mostra como é feito o mapeamento para essas duas situações. Para esse

mapeamento verifica-se duas condições: se o filho possui somente um pai e se o filho

possui mais de um pai.

Para a primeira condição é criada uma tabela para o filho, constituída de uma chave

primária, uma chave estrangeira referenciando a tabela pai; no caso de possuir atributos,

adiciona-se os atributos à tabela através do procedure

addAtributosElemento(filho). Na segunda condição, gera uma tabela para o

filho com uma coluna chave primária; possuindo atributos, adiciona-os na tabela. Cria-se

também uma tabela auxiliar que faz referência à tabela do filho e à tabela do pai.

A figura 25 descreve o mapeamento de elemento filho multivalorado e

elemento pai monovalorado.

49

se o filho for multivalorado e o pai monovalorado{se possui somente um pai{

gera uma tabela para o filho com uma coluna chaveprimaria e uma coluna chave estrangeira que referenciaa tabela pai;se possui atributos{addAtributosElemento(filho);}

}senão{gera uma tabela para o filho com uma coluna chaveprimaria;se possui atributos{addAtributosElemento(filho);}gera uma tabela auxiliar com duas coluna chavesestrangeiras uma que referencia o tabela filho e outraa tabela pai;} }

Figura 25 – Parte do algoritmo que trata de elemento filho multivalorado e

elemento pai monovalorado.

Para essa categoria são levadas em conta as mesmas condições das categorias

anteriores, como pode ser visto na figura 25.

A figura 26 descreve o mapeamento de elemento filho monovalorado e

elemento pai monovalorado.

se o filho for monovalorado e o pai monovalorado{se após o parêntese existir o símbolo “*” ou “+”{

se possui somente um pai{gera uma tabela para o filho com uma colunachave primaria e uma coluna chave estrangeiraque referencia a tabela pai;se possui atributos{addAtributosElemento(filho);}

}senão{gera uma tabela para o filho com uma colunachave primaria;se possui atributos{addAtributosElemento(filho);}gera uma tabela auxiliar com duas coluna chavesestrangeiras uma que referencia a tabela filho eoutra a tabela pai;

}senão{senão possuiSoFilhosMultivalorados(filho)

adiciona uma coluna chave estrangeira natabela pai;

senão{gera uma tabela para o filho com uma colunachave primaria e uma coluna chaveestrangeira que referencia a tabela pai;se possui atributos

addAtributosElemento(filho);}}}}

Figura 26 – Parte do algoritmo que trata de elemento filho monovalorado e elemento pai monovalorado.

50

Para fazer o mapeamento dessa categoria para um modelo relacional são levados

em conta duas situações: a primeira é se após o parêntese existe o símbolo “*” ou “+”

ex.: <!ELEMENT secao (paragrafo|figura|resumo|instituicao)+>; a

segunda é se não existe esses símbolos após o parêntese.

Na primeira situação verifica-se se o elemento possui somente um pai; essa

condição, sendo verdadeira, gera uma tabela para o filho com uma chave primária e uma

chave estrangeira referenciando a tabela pai e também verifica-se se o elemento possui

atributos e os adiciona na tabela filho. Caso o elemento filho possua mais de um filho, cria-

se uma tabela separada para o filho com os seus atributos, caso existam, e gera-se uma

tabela auxiliar que faz referência com a tabela do filho e a tabela do pai.

Para a segunda situação, são verificadas duas condições: se o elemento não possui

somente filhos multivalorados ex.: <!ELEMENT bibliografia (referencia+)>

e se o elemento só possui filhos multivalorados.

Para a primeira condição, simplesmente adiciona-se na tabela do pai uma coluna

chave estrangeira referenciando a tabela do filho, levando em conta se o elemento é

opcional ou obrigatório.

Na segunda condição gera-se uma tabela para o filho referenciando a tabela do pai;

caso possua atributos, eles são adicionados na tabela do filho. Na próxima seção têm-se

uma abordagem sobre o mapeamento de elemento vazio para um modelo relacional.

4.4.3 Elemento vazio

Para elemento vazio são levados em conta duas condições: elemento

monovalorado e elemento multivalorado. Para elemento monovalorado:

verifica-se se no pai do elemento existe um símbolo de “*” ou “+” após o parêntese, caso

exista, gera-se se uma tabela para o filho, com seus respectivos atributos e uma referência à

tabela do pai. Não existindo os símbolos, gera-se uma tabela para o filho, com seus

respectivos atributos, caso existam, e adiciona na tabela do pai uma coluna referenciando a

tabela do filho.

Elemento multivalorado: gera-se uma tabela para filho, com seus

respectivos atributos, caso existam, e uma tabela auxiliar relacionado com à tabela do filho

51

e à tabela do pai.

A figura 27 mostra o mapeamento desse tipo de elemento para um modelo

relacional.

se for vazio{se o filho for monovalorado{

verifica no pai se após o parêntese existe osímbolo “*” ou “+”{

gera uma tabela formada com o nome do pai e dofilho, com uma coluna chave primaria e uma chaveestrangeira que referencia a tabela pai;se possui atributos

addAtributosElemMisto(filho,pai);}senão{

gera uma tabela para o filho com uma colunachave primaria;se possui atributos

addAtributosElemento(filho);adiciona uma coluna chave estrangeira na tabelapai;}

}senão{gera uma tabela para o filho com uma colunachave primaria;se possui atributos

addAtributosElemento(filho);gera uma tabela auxiliar com duas colunas chavesestrangeiras uma que referencia a tabela dofilho e a outra a tabela do pai;}

}}

Figura 27 – Parte do algoritmo que trata de elemento vazio.

Para elemento vazio e elemento monovalorado existem duas situações:

elementos em que existe um símbolo de “*” ou “+” após o fechamento de parêntese de

seu pai (ex.: <!ELEMENT secao

(paragrafo|figura|resumo|instituicao)+> <!ELEMENT figura

EMPTY>); a segunda situação é quando isso não acontece.

Na primeira situação gera-se uma tabela, sendo que o nome da tabela será formado

pelo nome do filho junto ao nome do pai e essa tabela será composta por uma coluna chave

primária e uma coluna chave estrangeira referenciando a tabela pai; caso possua atributos,

eles são adicionado à tabela.

O elemento, estando na segunda situação, gera-se uma tabela para o filho com uma

coluna chave primária; caso possua atributos, eles são adicionados na tabela. Após,

52

adiciona-se na tabela do pai uma chave estrangeira que referencia a tabela do filho.

Para elemento vazio e elemento multivalorado cria-se uma tabela

para o filho com seus respectivos atributos, caso possua. Logo em seguida, gera-se uma

tabela auxiliar que referencia a tabela do pai e a tabela do filho.

Na próxima seção têm-se uma abordagem sobre o mapeamento de elemento

misto para um modelo relacional.

4.4.4 Elemento misto

O mapeamento de elemento misto para um modelo relacional é realizado da

seguinte forma: primeiramente, gera-se uma tabela em que o seu nome é composto pelo

nome do elemento filho e pelo nome do elemento pai. Caso possua atributos, eles são

adicionados à tabela através do procedure

addAtributosElemMisto(filho,pai); em seguida, percorre-se todos os filhos do

elemento, verificando as seguintes características: PCDATA, se o elemento filho

(filho do elemento misto) possui filhos, se o elemento filho é um PCDATA e se o

elemento filho é um elemento vazio.

Para PCDATA: o elemento possuindo somente um pai, gera-se uma tabela para o

PCDATA referenciando a tabela do pai; e caso possua mais de um pai, gera-se uma tabela

para o PCDATA e uma tabela auxiliar referenciando a tabela do PCDATA e a tabela do pai.

Quando elemento filho (filho do elemento misto) possui filhos: gera-se

uma tabela para o filho, com seus respectivos atributos; caso existam, e uma referência

com a tabela do pai, caso possua somente um pai. Possuindo mais de um pai, gera-se uma

tabela para o filho com seus respectivos atributos; caso existam, e uma tabela auxiliar

referenciando a tabela do filho e a tabela do pai.

Elemento filho (filho do elemento misto) é um PCDATA: ocorre da mesma

forma que a situação anterior.

Elemento vazio (filho do elemento misto): gera-se uma tabela para o filho,

com seus respectivos atributos; caso existam, e uma referência com a tabela do pai, caso

possua somente uma pai e o seu pai também possua semente um pai. Possuindo mais de

um pai, ambos os elementos, gera-se uma tabela para o filho com seus respectivos

atributos; caso existam, e uma tabela auxiliar referenciando a tabela do filho e a tabela do

53

pai.

Ainda nessa seção será abordado sobre esse mapeamento com mais detalhes. A

figura 28 mostra o início do mapeamento de elemento misto.

se for misto{gera uma tabela formada com o nome do pai e do filho, comuma coluna chave primaria e uma chave estrangeira quereferencia a tabela pai;se possui atributos{

addAtributosElemMisto(filho,pai);para cada filho do elemento misto{...}

}

Figura 28 – Inicio do algoritmo que trata de elemento misto.

Como pode ser visto na figura 28, após gerar a tabela para o elemento misto

percorre-se todos os filhos do elemento, fazendo o seu mapeamento para o modelo

relacional. Abaixo é descrito como são manipulados os filhos do elemento misto.

Primeiramente será tratado de elemento PCDATA.

se for PCDATA{se possui somente um pai{

gera uma tabela com uma coluna chave primaria, umacoluna chave estrangeira que referencia a tabela do paie uma coluna para o filho;

}senão{gera uma tabela para o filho com uma coluna chaveprimaria e uma coluna para o elemento filho;gera uma tabela auxiliar com duas coluna chavesestrangeira uma que referencia a tabela do filho e aoutra a tabela do pai;}

}

Figura 29 – Parte do algoritmo que trata de elemento misto – quando o filho do elemento misto é PCDATA.

Como mostra a figura 29, para elemento PCDATA faz-se duas verificações:

primeiro verifica-se se o elemento possui somente um pai; a segunda verificação é se o

elemento possui mais de um pai. Para a primeira condição, gera-se uma tabela para o

elemento referenciando a tabela do pai (elemento misto) e uma coluna para armazenar o

filho.

Na segunda condição gera-se uma tabela para o elemento PCDATA com uma coluna

chave primária e uma coluna para o elemento. Após, gera-se uma tabela auxiliar

54

referenciando a tabela do elemento misto a tabela do pai.

Caso o elemento não seja um PCDATA, percorre-se o documento e verifica-se onde

esse elemento é pai. Após encontrá-lo, são realizadas três condições: se o elemento

filho (filho do elemento misto) também possui filhos, se é um elemento

PCDATA e se é um elemento vazio.

A figura 30 mostra como é feito o mapeamento se o elemento filho também

possui filhos.

se o filho possui filho{se possui somente um pai{

gera uma tabela para o filho com uma coluna chaveprimário e uma coluna chave estrangeira quereferencia a tabela pai;se possui atributos{ addAtributosElemento(misto);}

}senão{gera uma tabela para filho com uma coluna chaveprimaria;se possui atributos{addAtributosElemento(misto);}gera uma tabela auxiliar com duas colunas chavesestrangeira uma que referencia a tabela do filho e aoutra a tabela do pai;}

}

Figura 30 – Parte do algoritmo que trata de elemento misto – quando o filhodo elemento misto possui filhos.

Como pode ser visto na figura 30, para esse tipo de elemento tem que ser analisados

duas condições: se o elemento filho do elemento misto possui somente um

pai; e se o elemento possui mais de um pai. Quando o elemento possui somente um pai,

gera-se uma tabela para o elemento filho com duas chaves, uma primária e outra

estrangeira que referencia a tabela do pai; caso possua atributos, eles são adicionados na

tabela.

Quando o elemento possui mais de um pai, gera-se uma tabela para o filho e

verifica-se se o mesmo possui atributos; se for verdade, adiciona-se os atributos à tabela.

Após, gera-se uma tabela auxiliar referenciando a tabela do filho e a tabela do pai.

A figura 31 mostra o mapeamento do elemento quando ele for um PCDATA.

55

se for um PCDATA{se possui somente um pai{

gera uma tabela para o filho com uma coluna chaveprimaria, uma coluna chave estrangeira que referenciaa tabela do pai e uma coluna para o elemento filho;se possui atributos{addAtributosElemento(misto);}

}senão{gera uma tabela para o filho com uma coluna chaveprimaria e uma coluna para o filho;se possui atributos{addAtributosElemento(misto);}gera uma tabela auxiliar com duas colunas chavesestrangeiras uma que referencia a tabela do filho e aoutra a tabela do pai;}

}

Figura 31 – Parte do algoritmo que trata de elemento misto – quando o filhodo elemento misto for um PCDATA.

A figura 31 descreve o mapeamento de quando o filho do elemento misto for do

tipo PCDATA. Como pode ser visto na figura 31, são realizadas duas verificações: se o

elemento possui somente um pai; e se o elemento possui mais de um pai. Para o elemento

que possui somente um pai, gera-se uma tabela referenciando a tabela do pai; caso possua

atributos, os mesmos são adicionados na tabela e também é adicionado na tabela uma

coluna para guardar o valor do elemento.

Quando o elemento possui mais de um pai, gera-se uma tabela para o filho com

uma coluna chave primária, uma coluna para o filho; caso possua atributos, os mesmos são

adicionados na tabela. Após, gera-se uma tabela auxiliar referenciando a tabela do filho e a

tabela do pai.

A figura 32 mostra o mapeamento de quando o filho do elemento misto

for um elemento vazio.

56

se for vazio{se possui somente um pai e seu pai possui somente um pai{

gera uma tabela para o filho com uma coluna chaveprimaria e uma coluna chave estrangeira que areferencia tabela pai;se possui atributos{ addAtributosElemento(misto);}

}senão{gera uma tabela para o filho com uma coluna chaveprimaria;se possui atributos{addAtributosElemento(misto);}gera uma tabela auxiliar com duas colunas chavesestrangeira uma que referencia a tabela do filho e aoutra a tabela do pai;}

}

Figura 32 – Parte do algoritmo que trata de elemento misto – quando o filhodo elemento misto for um elemento vazio.

Quando o filho do elemento misto for um elemento vazio verifica-

se duas condições: se o elemento filho possui somente um pai e se o seu pai (o

elemento misto) também possui somente um pai; e se o elemento filho possui mais de

um pai e se o seu pai (o elemento misto) também possui mais de um pai.

Para a primeira condição gera-se uma tabela para o filho com uma coluna chave

primária, uma coluna chave estrangeira que referencia a tabela do pai e seus atributos. Para

a segunda condição gera-se uma tabela para o filho com seus respectivos atributos e uma

tabela auxiliar referenciando a tabela do pai e a tabela do filho.

Na próxima seção têm-se uma abordagem do sistema implementado.

4.5 Sistema implementado

A implementação do algoritmo foi feita em Delphi 7. A ferramenta recebe um

documento XML (adquirido a partir do DTDParser do javacc), que é a representação da

DTD, e gera um script SQL (utilizado a sintaxe do SQL Server2000) . A figura 33 mostra a

interface do sistema implementado.

57

Figura 33 – Interface do sistema

Além de gerar os scripts SQL das DTDs, que é a sua função principal, o usuário

pode também realizar algumas operações básicas, como por exemplo, editar o documento

(mudar fonte, modificar o documento e dentre outras funcionalidades), imprimir etc. A

figura 34 mostra o modelo lógico relacional definido a partir do script SQL (da DTD da

figura 3) gerado pelo sistema implementado nesse trabalho.

58

Figura 34 – Modelo lógico relacional gerado a partir da DTD da figura 3.

Na próxima seção têm-se uma comparação entre os algoritmos apresentados na

seção 2.6 e o algoritmo desenvolvido nesse trabalho.

4.6 Comparação entre os algoritmos apresentados na revisão de literatura e o algoritmo desenvolvido nesse trabalho

Com base nos algoritmos apresentados na revisão de literatura e o algoritmo

desenvolvido nesse trabalho serão feitas algumas comparações:

1. Número de tabelas geradas: o número de tabelas geradas foi inferior a

praticamente todas as outras abordagens, com exceção da segunda

59

abordagem, que ficou com o mesmo número de tabelas. Entretanto, na

segunda abordagem, algumas tabelas geradas continham apenas a coluna

chave primária.

A vantagem de se obter um número menor de tabelas é que as consultas

tendem a apresentar uma melhor performance, uma vez que o número de

junções entre as tabelas é menor. Já com um número maior de tabelas,

obtém-se uma melhor normalização do modelo (menor redundância de

dados), mas isso aumenta a fragmentação e pode ocasionar perda de

performance;

2. Ordem dos elementos: somente a quarta abordagem (FLO 99) guarda a

ordem dos elementos.

A vantagem em guardar a ordem dos elementos é que , posteriormente,

pode-se recuperar o documento original do banco de dados;

3. A partir da DTD ou do XML: o algoritmo desenvolvido trabalha com base

em um DTD, assim como a primeira, a segunda e a terceira abordagens.

Somente a quarta abordagem baseia-se em um documento XML para a

geração de esquemas lógicos relacionais.

Ter como base uma DTD para gerar um modelo lógico relacional têm a

vantagem de que o modelo lógico gerado é válido para todos os documentos

XMLs válidos pela DTD. O caso de ter uma modelo relacional a partir de

um documento XML tem a desvantagem do modelo suportar somente uma

única estrutura (a estrutura do documento XML utilizada no mapeamento);

4. Informação não é perdida no mapeamento: tanto para o algoritmo

desenvolvido nesse trabalho quanto para os apresentados na revisão de

literatura não há perda no mapeamento.Todos os atributos e elementos são

mapeados para o modelo lógico relacional.

Guardar todas as informações contidas nos documentos pode gerar o

armazenamento de alguns dados desnecessários, como informações de

metadados armazenados em atributos, por exemplo. Por outro lado, todos os

dados do documento original são armazenados no banco;

5. Tabelas com apenas a chave primária: as abordagens apresentadas baseadas

em DTD geraram algumas tabelas com apenas a chave primária. Tabelas

60

apenas com chave primária devem ser analisadas e possivelmente integradas

a outras tabelas existentes no modelo. No algoritmo desenvolvido isso não

ocorre.

Essa situação ocorre em elementos em que todos os seus filhos são

multivalorados e no algoritmo desenvolvido ela está sendo tratada na parte

do algoritmo descrita na figura 26.

61

5. CONSIDERAÇÕES FINAIS E TRABALHOS FUTUROS

A proposta deste trabalho consistiu em definir uma algoritmo capaz de fazer o

mapeamento de uma DTD para um modelo lógico relacional, assim como a implementação

desse algoritmo.

Com o desenvolvimento do trabalho, foi possível gerar modelos lógicos relacionais

a partir de uma DTD, sem perder informações e mantendo a cardinalidade dos elementos e

atributos, possibilitando a extração de dados para o modelo lógico relacional de qualquer

documento XML válido pela DTD.

O DTDParser foi fundamental na leitura da DTD, permitindo gerar um documento

XML que representasse a DTD, fornecendo mais flexibilidade para trabalhar o

mapeamento. O XML Data Binding (Delphi) possibilitou fazer a leitura do documento

XML gerado pelo DTDParser, possibilitando assim a implementação do algoritmo.

Os principais problemas encontrados no desenvolvimento do trabalho foram:

mapeamento de elementos mistos; elementos complexos acrescidos do símbolo “*” e

“+”, como por exemplo, (<!ELEMENT secao

(paragrafo|figura|resumo|instituicao)+>); e elementos em que todos os

seus filhos são multivalorados. Essa última situação é uma das responsáveis pela criação de

tabelas com somente a chave primária, o que não acontece no algoritmo desenvolvido

nesse trabalho.

Como trabalhos futuros propõe-se adaptar ao algoritmo meios de mapear o caminho

(ordem) dos elementos e dos atributos do documento XML. Essa modificação facilitará a

recuperação do documento XML original. Um outro trabalho é o desenvolvimento de um

algoritmo que faça a recuperação do documento XML a partir do Banco de Dados

relacional.

O desenvolvimento desse trabalho possibilitou a definição de um algoritmo capaz

de fazer o mapeamento de uma DTD para um modelo lógico relacional e sua

implementação. Possibilitou também a exploração de componentes do Delphi (com por

62

exemplo, XML Data Binding), e de um parser gerado pelo javacc.

63

6. REFERÊNCIAS BIBLIOGRÁFICAS

(AHO et al 1995) AHO, Alred V., SETHI Ravi, ULLMAN, Jeffrey D.,

Compiladores Principios, Técnicas e Ferramentas, Tradução Daniel de Ariosto

Pinto, Editora: Afiliada, Rio de Janeiro, RJ 1995

(ANDERSON 2001) ANDERSON, R. et al. Profissional XML. Rio de Janeiro,

RJ: Editora Ciência Moderna LTDA., 2001.

(BOU 2001) BOURRET, R. Mapping DTDs to Databases. Maio 2001.

Disponível em:<http://www.xml.com/pub/a/2001/05/09/dtdtodbs.html>. Acessado

em 08/10/2003

(CHR 94) CHRISTOPHIDES, V. et al. From structured documents to novel

query facilities. SIGMOD Record, New York, v.23, n.2, p. 313-324, June. 1994.

(DB2 2003a) DB2 Universal, IBM CORPORATIO. Disponível em

<http://www.ibm.com/db2> . Acessado em 27/09/2003

(DB2 2003b) XML Extender Administration and Programming, IBM

CORPORATIO. Disponível em <http://www.ibm.com.db2> . Acessado em

27/09/2003

(DB2 2003c) XML Extender, IBM CORPORATIO. Disponível em < http://www-

3.ibm.com/software/data/db2/extenders/xmlext/xmliseries/index.html > . Acessado

em 27/09/2003

64

(DTDParser 2003) DTDParser, Disponível em:

<http://www.cobase.cs.ucla.edu/pub/javacc/DTDParser.jj>. Acessado em

08/10/2003

(FER 98) FERNANDEZ, M. et al. Catching the Boat with Strudel: Experiences

with a Web-Site Management System. SIGMOD Record, New York, v.27, n.2, p.

414, 1998. Trabalho apresentado na ACM SIGMOD Special Interest Group on

Management of Data, SIGMOD, 1998.

(FLO 99) FLORESCU, D. et al. A Performance Evaluation of Alternative

Mapping Schemes for Storing XML Data in a Relational Database. 1999.

(Technical Report, n. 3680). Disponível em: <

http://citeseer.nj.nec.com/florescu99performance.html>. Acesso em: 25/09/2003.

(JAVACC 2000) JAVACC, Java Compiler Compiler, JavaCC versão 3.2

binaries, Disponível em:

<https://javacc.dev.java.net/servlets/ProjectDocumentList>. Acessado em

06/10/2003

(LU et al 2003) LU, Shiyong, SUN, Yezhou, Atay, Mustafa, FOTOUHI, Farshad.

A New Inlining Algorithm for Mapping XML DTDs to Relational Schemas,

Department Of Computer Science Wayne State University Detroit, MI 48202,

2003. Disponível em: <http://citeseer.nj.nec.com/lu03new.html> . Acessado em

29/09/2003.

(MELLO et al, 2000) MELLO, Ronaldo dos Santos, KADE, Adrovane Marques,

DORNELES, C. F., BRAGANHOLO, V.,HEUSER, Carlos Alberto, Dados Semi-

estruturados (tutorial). Simpósio Brasileiro de Banco de Dados, 2000, João

Pessoa, PB. Tutoriais. João Pessoa: SBC, 2000. Disponível em:

<ftp://heuser.inf.ufrgs.br/pub/pdf/sbbd00-tutorial.pdf>. Acesso em: 05/02/2003.

65

(McH2 97) McHUGH, J. et al. Lore: A Database Management System for

Semistructured Data. Disponível em: <http://www-

db.stanford.edu/lore/pubs/lore97.pdf>.SIGMOD Record, New York, v.26, n.3, p.

54-66, Sept. 1997. Acesso em: 26/09/2003.

(ORACLE 2002) ORACLE, Corporation, LORENTZ, Diana, GREGOIRE, Joan.

Oracle9i SQL Reference, Release 2 (9.2). outubro 2002. Disponívle em:

<ttp://www.arb.ca.gov/app/doc/oracle/doc92/SQLRef.pdf>. Acesso em: 26/09/2003

(SACCOL 2001) SACCOL, Deise de Brum, Materialização de Visões XML.

Dissertação (Mestrado) 2001. Programa de Pós-Graduação em Computação, Porto

Alegre, BR-RS, 2001. Universidade Federal do Rio Grande do Sul, Porto Alegre:

PPGC da UFRGS, 2001. 85 f:il. Orientador: Heuser, Carlos Alberto.

(SHA 99) SHANMUGASUNDARAM, J. et al. Relational Databases for

Querying XML Documents: Limitations and Opportunities. In:

INTERNATIONAL CONFERENCE ON VERY LARGE DATA BASES, 25.,

1999, Edinburg, UK. Proceedings... Edinburg: VLDB Endowment, 1999.

(SERVER 2000a) Microsoft SQL Server. Disponível em:

<http://www.microsoft.com/sql/evaluation/features/RichXML.asp> . Acessado em

27/09/2003.

(SERVER 2000b) Microsoft SQL Server. Disponível em: <

http://msdn.microsoft.com/library/default.asp?url=/library/en-

us/dnsqlmag2k/html/TheXMLFiles.asp > . Acessado em 27/09/2003.

(ZWO 99) ZWOL, R. et al. Modelling and querying semistructured data with

MOA. In: WORKSHOP ON SEMI-STRUCTURED DATA AND

NONSTANDARD DATA FORMATS, 1999, Jerusalem, IS. Proceedings...

Jerusalem: VLDB Endowment, 1999.

66

ANEXOS

DTDParser.jj e a Implementação

67

DTDParse.jj

/*** name: DTDParser.jj* modified: Apr 2, 2001* author: John Gebbie* email: [email protected]*/

options {DEBUG_PARSER = false;

}

PARSER_BEGIN(DTDParser)

import java.io.InputStream;import java.io.FileInputStream;import java.io.FileNotFoundException;

public class DTDParser{

public static void parse(InputStream aInSt) throws ParseException {// create a parser (this object)DTDParser parser = new DTDParser(aInSt);// parse!parser.dtd();

}

public static void main(String[] args) throws ParseException,FileNotFoundException {

parse(new FileInputStream(args[0]));}

}

PARSER_END(DTDParser)

TOKEN :{

<LETTER: [ "A"-"Z", "a"-"z" ] >| <DIGIT: [ "0"-"9" ] >| <NAMECHAR: ( <LETTER> | <DIGIT> | "." | "-" | "_" | ":" ) >| <FIXED: "#FIXED" >| <IMPLIED: "#IMPLIED" >| <PCDATA: "#PCDATA" >| <REQUIRED: "#REQUIRED" >| <CDATA: "CDATA" >| <ANY: "ANY" >| <EMPTY: "EMPTY" >| <ID: "ID" >| <IDREF: "IDREF" >| <IDREFS: "IDREFS" >| <ENTITY: "ENTITY" >| <ENTITIES: "ENTITIES" >| <NMTOKEN: "NMTOKEN" >| <NMTOKENS: "NMTOKENS" >| <NOTATION: "NOTATION" >| <NAME: ( <LETTER> | "_" | ":" ) ( <NAMECHAR> )* >

68

| <QUOTEDSTR: ( "'" (~["'"])* "'" ) | ( "\"" (~["\""])* "\"") >}

SKIP :{

< ( " " | "\t" | "\n" | "\r" )+ >// comment decl updated by Gagandeep Bhatia

[mailto:[email protected]]| < "<!--" ( ~["-"] | ( "-" ~["-"] ) )* "-->" >| < "<?" (~[">"])* ">" >}

void dtd() :{}{

{System.out.println("<DTD>");}( elementDecl() | attListDecl() )* <EOF>{System.out.println("</DTD>");}

}

void elementDecl() :{ Token t = new Token();}{

{System.out.println("<Elemento>");}

{System.out.println("<pai>");}

"<!ELEMENT" t = <NAME> contentSpec() ">"

{System.out.println("<nome>");}

{System.out.println(t.image);}

{System.out.println("</nome>");}

{System.out.println("</pai>");}

{System.out.println("</Elemento>");}}

void contentSpec() :{}{

{System.out.println("<tipo>");}{System.out.println("EMPTY");}<EMPTY>{System.out.println("</tipo>");}

|{System.out.println("<tipo>");}{System.out.println("ANY");}<ANY>{System.out.println("</tipo>");}

| LOOKAHEAD(3) mixed() | LOOKAHEAD(2) pcdata() | children()}

void pcdata() :{

69

}{

{System.out.println("<pcdata>");}

"(" <PCDATA> ")"

{System.out.println("PCDATA");}

{System.out.println("</pcdata>");}

}

void mixed() :{ Token t = new Token();}{

{System.out.println("<misto>");}

"(" {System.out.println("<nome>");} <PCDATA>{System.out.println("PCDATA");} {System.out.println("</nome>");} ("|" (t=<NAME> ){System.out.println("<nome>");}

{System.out.println(t.image);}

{System.out.println("</nome>");})+ ")*"

{System.out.println("</misto>");}

}

void children() :{}{

seqchoice() [modifier()]

}

void seqchoice() :{}{

"(" cp() ( choice() | seq() ) ")"}

void choice() :{}

70

{

( "|" cp() )+

}

void seq() :{}{

( "," cp() )*

}

void cp() :{ Token t = new Token();}{

{System.out.println("<filho>");}( t=<NAME> | seqchoice() ) [modifier()]

{System.out.println("<nome>");}

{System.out.println(t.image);}

{System.out.println("</nome>");}

{System.out.println("</filho>");}

}

void modifier() :{}{

{System.out.println("<modifier>");} {System.out.println("*");}"*" {System.out.println("</modifier>");}

| {System.out.println("<modifier>");} {System.out.println("+");}"+" {System.out.println("</modifier>");}

| {System.out.println("<modifier>");} {System.out.println("?");}"?" {System.out.println("</modifier>");}

}

void attListDecl() :{ Token t = new Token();}{

{System.out.println("<Atributos>");}"<!ATTLIST" t=<NAME> ( attribDef() )* ">"

{System.out.println("<ElementoRef>");}

{System.out.println(t.image);}

{System.out.println("</ElementoRef>");}

71

{System.out.println("</Atributos>");}

}

void attribDef() :{ Token t = new Token();}{

{System.out.println("<Atributo>");}

t=<NAME> attribType() defaultDecl()

{System.out.println("<nome>");}

{System.out.println(t.image);}

{System.out.println("</nome>");}

{System.out.println("</Atributo>");}

}

void attribType() :{}{

stringType() | tokenizedType() | enumeratedType()}

void stringType() :{}

{{System.out.println("<tipo>");}

{System.out.println("CDATA");} <CDATA>

{System.out.println("</tipo>");}

}

void tokenizedType() :{}{

{System.out.println("<tipo>");}

{System.out.println("ID");} <ID>{System.out.println("</tipo>");}|{System.out.println("<tipo>");}{System.out.println("IDREF");}<IDRE

F>{System.out.println("</tipo>");}|{System.out.println("<tipo>");}{System.out.println("IDREFS");}<IDR

EFS>{System.out.println("</tipo>");}|{System.out.println("<tipo>");}{System.out.println("ENTITY");}<ENT

ITY>{System.out.println("</tipo>");}|{System.out.println("<tipo>");}{System.out.println("ENTITIES");}<E

NTITIES>{System.out.println("</tipo>");}

72

|{System.out.println("<tipo>");}{System.out.println("NMTOKEN");}<NMTOKEN>{System.out.println("</tipo>");}

|{System.out.println("<tipo>");}{System.out.println("NMTOKENS");}<NMTOKENS>{System.out.println("</tipo>");}

}

void enumeratedType() :{}{

( notationType() | enumeration() )}

void notationType() :{Token t = new Token();}{

<NOTATION> "(" {System.out.println("<notation>");}t=<NAME> {System.out.println(t.image);}{System.out.println("</notation>");}

( "|" {System.out.println("<notation>");}t=<NAME> {System.out.println(t.image);}{System.out.println("</notation>");})* ")"

}

void enumeration() :{Token t = new Token();}{

"(" {System.out.println("<enumeration>");} t=<NAME>{System.out.println(t.image);}

{System.out.println("</enumeration>");}

( "|"{System.out.println("<enumeration>");}t=<NAME>{System.out.println(t.image);}

{System.out.println("</enumeration>");})* ")"

}

void defaultDecl() :{}{

{System.out.println("<DeclaracaoDefault>");}

<REQUIRED>{System.out.println("REQUIRED");}{System.out.println("</DeclaracaoDefault>");}

|{System.out.println("<DeclaracaoDefault>");}{System.out.println("IMPLIED");}<IMPLIED>{System.out.println("</DeclaracaoDefault>");}

|{System.out.println("<DeclaracaoDefault>");}{System.out.println("FIXED");}{System.out.println("</DeclaracaoDefault>");} ( [ <FIXED> ]attribValue() )

73

}

void attribValue() :{Token t = new Token();}{

{System.out.println("<attribValue>");}

t=<QUOTEDSTR>

{System.out.println(t.image);}

{System.out.println("</attribValue>");}

}

74

Implementação

unit Unit_principal;

interface

usesWindows, Messages, SysUtils, Variants, Classes, Graphics, Controls,

Forms,Dialogs, dtd, StdCtrls, Menus, Grids, ValEdit, Buttons, ExtCtrls,ComCtrls, ShellApi, WinTypes, WinProcs;

typeTForm_principal = class(TForm)

MainMenu1: TMainMenu;Arquivo: TMenuItem;Abrir: TMenuItem;Sair: TMenuItem;Salvar: TMenuItem;OpenDialog: TOpenDialog;Save: TSaveDialog;Mapeador: TMenuItem;DTDMR: TMenuItem;StatusBar1: TStatusBar;Panel: TPanel;SB_abrir: TSpeedButton;SP_salvar: TSpeedButton;SB_limpar: TSpeedButton;SB_mapeador: TSpeedButton;SB_sair: TSpeedButton;Label_tab: TLabel;Editar: TMenuItem;Limpar: TMenuItem;Ajuda: TMenuItem;Sobre: TMenuItem;Fonte: TMenuItem;FontDialog: TFontDialog;ValueListEditorTb: TValueListEditor;SB_font: TSpeedButton;PrintDialog: TPrintDialog;SpeedButton1: TSpeedButton;RichEdit: TRichEdit;Imprimir1: TMenuItem;procedure AbrirClick(Sender: TObject);procedure SalvarClick(Sender: TObject);procedure SairClick(Sender: TObject);procedure DTDMRClick(Sender: TObject);procedure SB_abrirClick(Sender: TObject);procedure SP_salvarClick(Sender: TObject);procedure SB_mapeadorClick(Sender: TObject);procedure SB_limparClick(Sender: TObject);procedure SB_sairClick(Sender: TObject);procedure LimparClick(Sender: TObject);

75

procedure FonteClick(Sender: TObject);procedure SB_fontClick(Sender: TObject);procedure SpeedButton1Click(Sender: TObject);procedure Imprimir1Click(Sender: TObject);

private{ Private declarations }

public{ Public declarations }cam: WideString;dtd: IXMLDTDType; elemento: IXMLElementoTypeList; atributos:

IXMLAtributosTypeList;procedure algoritmo();function getNumeroPai(str_filho: AnsiString): Integer;procedure addAtributosElementoPcdata(str_pai: AnsiString;

ElementoRef: AnsiString; modifier: AnsiString; cont_pai: Integer);procedure addAtributosElemento(ElementoRef: AnsiString);procedure addAtributosElemMisto(ElementoRef: AnsiString; str_pai:

AnsiString);function possuiAtributos(str_filho: AnsiString): Boolean;function possuiSoFilhosMultivalorados(str_elemento: AnsiString):

Boolean;function getKeyTb(str: AnsiString): Integer;procedure fileAbrir();procedure fileSave();

end;

varForm_principal: TForm_principal;

implementation

uses XMLIntf, Math;

{$R *.dfm}//----------procedure TForm_principal.fileAbrir();-----------------------------procedure TForm_principal.fileAbrir();

var str_file,str_file_aux: AnSistring;retornoShellex: Integer;

beginif OpenDialog.Execute thenbegin

str_file:=OpenDialog.FileName;try

str_file_aux:= 'DTDParser '+ str_file;if (DirectoryExists('C:\Program Files\Mapeador DTD\Mapeador

DTD\DTDParser')) then

retornoShellex:=ShellExecute(Application.Handle,'Open','java',PAnsiChar(str_file_aux),'C:\Program Files\Mapeador DTD\MapeadorDTD\DTDParser',SW_SHOWNORMAL)//SW_HIDE

else

retornoShellex:=ShellExecute(Application.Handle,'Open','java',Pchar(str_file_aux),'C:\Arquivos de programas\Mapeador DTD\MapeadorDTD\DTDParser',SW_SHOWNORMAL);//SW_HIDE

Delete(str_file,Pos('.',str_file),4);cam:= str_file+'.xml';

76

Sleep(retornoShellex*100);dtd:=LoadDTD(cam);elemento:=dtd.Elemento;atributos:=dtd.Atributos;RichEdit.Clear;ValueListEditorTb.Strings.Clear;RichEdit.Lines.Add(dtd.XML);SB_mapeador.Enabled:=True;DTDMR.Enabled:=True;Label_tab.Caption:='Representação do DTD em XML';except

ShowMessage('Arquivo incompatível!')end;

end;end;//----procedure TForm_principal.fileSave();------------------------------------procedure TForm_principal.fileSave();

var file_dados: TStringList;begin

file_dados:= TStringList.Create;if Save.Execute thenbegin

tryfile_dados.Add(RichEdit.Text);file_dados.SaveToFile(Save.FileName);ShowMessage('Arquivo salvo com sucesso!!');

finallyfile_dados.Free;

end;end;

end;//------function TForm_principal.getKeyTb(str: AnsiString): Integer;---------function TForm_principal.getKeyTb(str: AnsiString): Integer;

var z,pos_tb: Integer;begin

z:=1;pos_tb:=0;while z < ValueListEditorTb.RowCount dobegin

if ValueListEditorTb.Keys[z]=str thenbegin

pos_tb:=z;z:=ValueListEditorTb.RowCount;

end;//if ValueListEditorTb.Keys[z]='tb_'+str_pai thenz:=z+1;

end;//while z < ValueListEditorTb.RowCount dogetKeyTb:= pos_tb;

end;//------------------------------getNumeroPai--------------------------------function TForm_principal.getNumeroPai(str_filho: AnsiString): Integer;

var cont_pai,j,i: Integer;begin

cont_pai:=0;for j:=0 to elemento.Count - 1 dobegin

77

if elemento.Items[j].Pai.Filho.Count > 0 thenbegin

for i:=0 to elemento.Items[j].Pai.Filho.Count -1 dobegin

if Trim(elemento.Items[j].Pai.Filho.Items[i].Nome) =str_filho then

cont_pai:= cont_pai +1;end;//for i:=0 to elemento.Items[j].Pai.Filho.Count -1 do

end;//if elemento.Items[j].Pai.Filho.Count > 0 thenif elemento.Items[j].Pai.Misto.Count > 0 thenbegin

for i:=0 to elemento.Items[j].Pai.Misto.Count -1 dobegin

if Trim(elemento.Items[j].Pai.Misto.Nome[i]) = str_filhothen

cont_pai:= cont_pai +1;end;//for i:=0 to elemento.Items[j].Pai.Misto.Count -1 do

end;//if elemento.Items[j].Pai.Misto.Count > 0 thenend;//for j:=0 to elemento.Count - 1 dogetNumeroPai:=cont_pai;

end;//----------------------------functionTForm_principal.possuiSoFilhosMultivalorados(str_elemento: AnsiString):Boolean;----------function TForm_principal.possuiSoFilhosMultivalorados(str_elemento:AnsiString): Boolean;

var cont,j,i,aux: Integer;achou: Boolean; modifier: AnsiString;

begincont:=0;achou:=True;j:=0;while j < elemento.Count dobegin

aux:=j;if Trim(elemento.Items[aux].Pai.Nome) = str_elemento thenbegin

j:=elemento.Count;for i:=0 to elemento.Items[aux].Pai.Filho.Count -1 dobegin

modifier:=Trim(elemento.Items[aux].Pai.Filho.Items[i].Modifier);if (modifier = '') or (modifier='?') then

cont:= cont+1;end;//for i:=0 to elemento.Items[j].Pai.Filho.Count -1 do

end;//if elemento.Items[j].Pai.Filho.Count > 0 thenj:=j+1;

end;//while j < elemento.Count doif cont > 0 then

achou:=False;possuiSoFilhosMultivalorados:=achou;

end;//----------------------------function possuiAtributos(str_filho:AnsiString): Boolean;---function TForm_principal.possuiAtributos(str_filho: AnsiString): Boolean;

var i: Integer;achou: Boolean;

begini:=0;

78

achou:=False;while i < atributos.Count dobegin

if Trim(atributos.Items[i].ElementoRef) = str_filho thenbegin

achou:= True;i:=atributos.Count;

end;//if Trim(atributos.Items[i].ElementoRef) = str_filho theni:= i+1;

end;//while i < to atributos.Count dopossuiAtributos:= achou;

end;//--------addAtributosElementoPcdata(str_pai,str_filho:AnsiString,cont_pai: Integer);------------procedure TForm_principal.addAtributosElementoPcdata(str_pai: AnsiString;ElementoRef: AnsiString; modifier: AnsiString; cont_pai: Integer);

var i,j,pos_tb: Integer;key_tb,nome_atributo: AnsiString;

begini:=0;while i < atributos.Count dobegin

if Trim(atributos.Items[i].ElementoRef)= ElementoRef thenbegin

for j:=0 to atributos.Items[i].Atributo.Count - 1 dobegin

if Trim(atributos.Items[i].Atributo.Items[j].Tipo) <>'ID' then

begin

nome_atributo:=Trim(atributos.Items[i].Atributo.Items[j].Nome);if (cont_pai = 1) and ((modifier='') or

(modifier='?'))thenbegin

pos_tb:=getKeyTb('tb_'+str_pai);key_tb:='tb_'+str_pai;if pos_tb > 0 thenbegin

ifTrim(atributos.Items[i].Atributo.Items[j].Tipo)= 'IDREF' then

begin

ValueListEditorTb.InsertRow(key_tb,Trim(ValueListEditorTb.Values[key_tb])+','+nome_atributo+' Integer not null',True);

ValueListEditorTb.DeleteRow(pos_tb);end//if

Trim(atributos.Items[i].Atributo.Items[j].Tipo)= 'IDREF' thenelsebegin

ifTrim(atributos.Items[i].Atributo[j].DeclaracaoDefault) <>'IMPLIED' then

begin

ValueListEditorTb.InsertRow(key_tb,Trim(ValueListEditorTb.Values[key_tb])+','+nome_atributo+' nvarchar(250) not null',True);

ValueListEditorTb.DeleteRow(pos_tb);end//if

Trim(atributos.Items[i].Atributo[j].DeclaracaoDefault) <>'IMPLIED' thenelse

79

begin

ValueListEditorTb.InsertRow(key_tb,Trim(ValueListEditorTb.Values[key_tb])+','+nome_atributo+' nvarchar(250)',True);

ValueListEditorTb.DeleteRow(pos_tb);end;//else

end;//elseend;//if pos_tb > 0 then

end//if cont_pai = 1 and ((modifier='') or(modifier='?'))then

elsebegin

if ((cont_pai = 1) and ((modifier='*') or(modifier='+'))) or (cont_pai > 1) then

beginpos_tb:=getKeyTb('tb_'+ElementoRef);key_tb:='tb_'+ElementoRef;if pos_tb > 0 thenbegin

ifTrim(atributos.Items[i].Atributo.Items[j].Tipo)= 'IDREF' then

begin

ValueListEditorTb.InsertRow(key_tb,Trim(ValueListEditorTb.Values[key_tb])+','+nome_atributo+' Integer not null',True);

ValueListEditorTb.DeleteRow(pos_tb);end//if

Trim(atributos.Items[i].Atributo.Items[j].Tipo)= 'IDREF' thenelsebegin

ifTrim(atributos.Items[i].Atributo[j].DeclaracaoDefault) <>'IMPLIED' then

begin

ValueListEditorTb.InsertRow(key_tb,Trim(ValueListEditorTb.Values[key_tb])+','+nome_atributo+' nvarchar(250) not null',True);

ValueListEditorTb.DeleteRow(pos_tb);end//if

Trim(atributos.Items[i].Atributo[j].DeclaracaoDefault) <>'IMPLIED' thenelsebegin

ValueListEditorTb.InsertRow(key_tb,Trim(ValueListEditorTb.Values[key_tb])+','+nome_atributo+' nvarchar(250)',True);

ValueListEditorTb.DeleteRow(pos_tb);end;//else

end;//elseend;//if pos_tb > 0 then

end;// if ((cont_pai = 1) and ((modifier='*') or(modifier='+'))) or (cont_pai > 1) then

end;//elseend;//if Trim(atributos.Items[i].Atributo.Items[j].Tipo)

<> 'ID' thenend;//for j:=0 to atributos.Items[i].Atributo.Count - 1 do}i:=atributos.Count;

end;//if Trim(atributos.Items[i].ElementoRef)= ElementoRef theni:=i+1;

80

end;end;//-------------------------addAtributosElemento(ElementoRef: AnsiString)-------procedure TForm_principal.addAtributosElemento(ElementoRef: AnsiString);

var j,i,pos_tb: Integer;key_tb,nome_atributo: AnsiString;

begini:=0;while i < atributos.Count dobegin

if Trim(atributos.Items[i].ElementoRef)= ElementoRef thenbegin

for j:=0 to atributos.Items[i].Atributo.Count - 1 dobegin

if Trim(atributos.Items[i].Atributo.Items[j].Tipo) <>'ID' then

begin

nome_atributo:=Trim(atributos.Items[i].Atributo.Items[j].Nome);pos_tb:=getKeyTb('tb_'+ElementoRef);key_tb:='tb_'+ElementoRef;if pos_tb > 0 thenbegin

ifTrim(atributos.Items[i].Atributo.Items[j].Tipo)= 'IDREF' then

begin

ValueListEditorTb.InsertRow(key_tb,Trim(ValueListEditorTb.Values[key_tb])+','+nome_atributo+' integer not null',True);

ValueListEditorTb.DeleteRow(pos_tb);end//if

Trim(atributos.Items[i].Atributo.Items[j].Tipo)= 'IDREF' thenelsebegin

ifTrim(atributos.Items[i].Atributo[j].DeclaracaoDefault) <>'IMPLIED' then

begin

ValueListEditorTb.InsertRow(key_tb,Trim(ValueListEditorTb.Values[key_tb])+','+nome_atributo+' nvarchar(250) not null',True);

ValueListEditorTb.DeleteRow(pos_tb);end//if

Trim(atributos.Items[i].Atributo[j].DeclaracaoDefault) <>'IMPLIED' thenelsebegin

ValueListEditorTb.InsertRow(key_tb,Trim(ValueListEditorTb.Values[key_tb])+','+nome_atributo+' nvarchar(250)',True);

ValueListEditorTb.DeleteRow(pos_tb);end;//else

end;//elseend;//if pos_tb > 0 then

end;//if Trim(atributos.Items[i].Atributo.Items[j].Tipo)<> 'ID' then

end;//for j:=0 to atributos.Items[i].Atributo.Count - 1 doi:=atributos.Count

end;//if Trim(atributos.Items[i].ElementoRef)= ElementoRef theni:= i+1;

81

end;//while i < atributos.Count doend;//--------TForm_principal.addAtributosElemMisto(ElementoRef: AnsiString;str_pai: AnsiString);-------procedure TForm_principal.addAtributosElemMisto(ElementoRef: AnsiString;str_pai: AnsiString);

var j,i,pos_tb: Integer;key_tb,nome_atributo: AnsiString;

begini:=0;while i < atributos.Count dobegin

if Trim(atributos.Items[i].ElementoRef)= ElementoRef thenbegin

for j:=0 to atributos.Items[i].Atributo.Count - 1 dobegin

if Trim(atributos.Items[i].Atributo.Items[j].Tipo) <>'ID' then

begin

nome_atributo:=Trim(atributos.Items[i].Atributo.Items[j].Nome);pos_tb:=getKeyTb('tb_'+ElementoRef+'_'+str_pai);key_tb:='tb_'+ElementoRef+'_'+str_pai;if pos_tb > 0 thenbegin

ifTrim(atributos.Items[i].Atributo.Items[j].Tipo)= 'IDREF' then

begin

ValueListEditorTb.InsertRow(key_tb,Trim(ValueListEditorTb.Values[key_tb])+','+nome_atributo+' integer not null',True);

ValueListEditorTb.DeleteRow(pos_tb);end//if

Trim(atributos.Items[i].Atributo.Items[j].Tipo)= 'IDREF' thenelsebegin

ifTrim(atributos.Items[i].Atributo[j].DeclaracaoDefault) <>'IMPLIED' then

begin

ValueListEditorTb.InsertRow(key_tb,Trim(ValueListEditorTb.Values[key_tb])+','+nome_atributo+' nvarchar(250) not null',True);

ValueListEditorTb.DeleteRow(pos_tb);end//if

Trim(atributos.Items[i].Atributo[j].DeclaracaoDefault) <>'IMPLIED' thenelsebegin

ValueListEditorTb.InsertRow(key_tb,Trim(ValueListEditorTb.Values[key_tb])+','+nome_atributo+' nvarchar(250)',True);

ValueListEditorTb.DeleteRow(pos_tb);end;//else

end;//elseend;//if pos_tb > 0 then

end;//if Trim(atributos.Items[i].Atributo.Items[j].Tipo)<> 'ID')

end;//for j:=0 to atributos.Items[i].Atributo.Count - 1 doi:=atributos.Count

end;//if Trim(atributos.Items[i].ElementoRef)= ElementoRef then

82

i:= i+1;end;//while i < atributos.Count do

end;//-------------------------algoritmo()-------------------------------------------procedure TForm_principal.algoritmo();

var j,i,y,pos_tb,aux_misto,aux,cont_pai,pos_tb_filho,cont_filho:Integer;

str_filho,modifier,str_pai,modifier_pai,modifier_aux,key_tb,pcdata,tipo,str_nome_misto,pcdata_misto,tipo_misto,key_tb_filho: AnsiString;achou: Boolean;

beginfor j:=0 to elemento.Count -1 dobegin

str_pai:= Trim(elemento.Items[j].Pai.Nome);modifier_pai:=Trim(elemento.Items[j].Pai.Modifier);for i:=0 to elemento.Items[j].Pai.Filho.Count -1 dobegin

str_filho:= Trim(elemento.Items[j].Pai.Filho.Items[i].Nome);modifier:=

Trim(elemento.Items[j].Pai.Filho.Items[i].Modifier);y:=1;while y <= elemento.Count-1 dobegin

if Trim(elemento.Items[y].Pai.Nome)=str_filho thenbegin

pcdata:=Trim(elemento.Items[y].Pai.Pcdata);tipo:= Trim(elemento.Items[y].Pai.Tipo);if elemento.Items[y].Pai.Filho.Count = 0 thenbegin

achou:=False;if getKeyTb('tb_'+str_pai) > 0 thenbegin

pos_tb:=getKeyTb('tb_'+str_pai);key_tb:='tb_'+str_pai;achou:=True;

end;//if getKeyTb('tb_'+str_pai) > 0 thenif not achou thenbegin

//cria uma tabela para o pai

ValueListEditorTb.InsertRow('tb_'+str_pai,'create table tb_'+str_pai+'(id_'+str_pai+' Integer not null, primary key (id_'+str_pai+')',True);

if possuiAtributos(str_pai) thenaddAtributosElemento(str_pai);

if getKeyTb('tb_'+str_pai) > 0 thenbegin

pos_tb:=getKeyTb('tb_'+str_pai);key_tb:='tb_'+str_pai;

end;//if getKeyTb('tb_'+str_pai) > 0 thenend;//if achou=False then

if pcdata ='PCDATA' thenbegin

cont_pai:=getNumeroPai(str_filho);if ((modifier_pai='+') or (modifier_pai='*'))

thenbegin

//cria uma tabela para o filho

83

ValueListEditorTb.InsertRow('tb_'+str_filho+'_'+str_pai,'create tabletb_'+str_filho+'_'+str_pai+' (id_'+str_filho+' Integer not null, primarykey (id_'+str_filho+'), id_'+str_pai+' Integer not null, foreign key(id_'+str_pai+') references tb_'+str_pai+', '+str_filho+' nvarchar(250)not null',True);

if possuiAtributos(str_filho) thenbegin

addAtributosElementoPcdata(str_pai,str_filho,modifier,cont_pai);end;//if possuiAtributos(str_filho)=True

thenend//if ((modifier_pai='+') or

(modifier_pai='*')) thenelsebegin

if (modifier='') or (modifier = '?') thenbegin

if not possuiAtributos(str_filho)then

begin//adiciona uma coluna na tabela

paiif modifier='' thenbegin

ValueListEditorTb.InsertRow('tb_'+str_pai,ValueListEditorTb.Values[key_tb]+', '+str_filho+' nvarchar(250) not null',True);

ValueListEditorTb.DeleteRow(pos_tb);end;//if modifier='' thenif modifier='?' thenbegin

ValueListEditorTb.InsertRow('tb_'+str_pai,ValueListEditorTb.Values[key_tb]+', '+str_filho+' nvarchar(250)',True);

ValueListEditorTb.DeleteRow(pos_tb);end;//if modifier='?' then

end//if possuiAtributos(str_filho)=false then

elsebegin

if cont_pai = 1 thenbegin

if modifier='?' thenbegin

ValueListEditorTb.InsertRow('tb_'+str_pai,ValueListEditorTb.Values[key_tb]+', '+str_filho+' nvarchar(250)',True);

ValueListEditorTb.DeleteRow(pos_tb);end//if modifier='?' thenelsebegin

ValueListEditorTb.InsertRow('tb_'+str_pai,ValueListEditorTb.Values[key_tb]+', '+str_filho+' nvarchar(250) not null',True);

84

ValueListEditorTb.DeleteRow(pos_tb);end;//else

end//if cont_pai = 1 thenelsebegin

achou:=False;if getKeyTb('tb_'+str_filho)

> 0 thenbegin

achou:=True;end;//if

getKeyTb('tb_'+str_filho) > 0 thenif not achou thenbegin

ValueListEditorTb.InsertRow('tb_'+str_filho,'create tabletb_'+str_filho+' (id_'+str_filho+' Integer not null, primary key(id_'+str_filho+'), '+str_filho+' nvarchar(250) not null',True);

if modifier ='?' thenbegin //adiciona o id

do tb filho na tabela pai

ValueListEditorTb.InsertRow('tb_'+str_pai,ValueListEditorTb.Values[key_tb]+', id_'+str_filho+' Integer, foreign key (id_'+str_filho+') referencestb_'+str_filho,True)

end//if modifier ='?'then

elsebegin

ValueListEditorTb.InsertRow('tb_'+str_pai,ValueListEditorTb.Values[key_tb]+', id_'+str_filho+' Integer not null, foreign key (id_'+str_filho+')references tb_'+str_filho,True);

end;//else

ValueListEditorTb.DeleteRow(pos_tb);end;//else

addAtributosElementoPcdata(str_pai,str_filho,modifier,cont_pai);end;//if achou=False then

end;//elseend//if modifier='' or modifier = '?'

thenelsebegin

if (modifier='*') or (modifier = '+')then

beginif not possuiAtributos(str_filho)

thenbegin

//gera uma nova tabela com oid do pai

ValueListEditorTb.InsertRow('tb_'+str_filho+'_'+str_pai,'create tabletb_'+str_filho+'_'+str_pai+' (id_'+str_filho+' Integer not null, primarykey (id_'+str_filho+'), id_'+str_pai+' Integer not null, foreign key(id_'+str_pai+') references tb_'+str_pai+', '+

85

str_filho+' nvarchar(250) notnull',True);

end//if notpossuiAtributos(str_filho) then

elsebegin

if cont_pai =1 thenbegin

//gera uma nova tabelacom o id do pai

ValueListEditorTb.InsertRow('tb_'+str_filho,'create tabletb_'+str_filho+' (id_'+str_filho+' Integer not null, primary key(id_'+str_filho+'), id_'+str_pai+' Integer not null, foreign key(id_'+str_pai+') references tb_'+str_pai+', '+

str_filho+' nvarchar(250)not null',True);

addAtributosElementoPcdata(str_pai,str_filho,modifier,cont_pai);end//if cont_pai:=1 thenelsebegin

achou:=False;if

getKeyTb('tb_'+str_filho) > 0 thenbegin

achou:=True;end;//if

getKeyTb('tb_'+str_filho) > 0 thenif not achou thenbegin

//cria uma tabelapara o filho

ValueListEditorTb.InsertRow('tb_'+str_filho,'create tabletb_'+str_filho+' (id_'+str_filho+' Integer not null, primary key(id_'+str_filho+')',True);

addAtributosElementoPcdata(str_pai,str_filho,modifier,cont_pai);end;//if achou=False then//cria uma tabela

auxiliar com o id do pai e o id do filho

ValueListEditorTb.InsertRow('tb_'+str_filho+'_'+str_pai,'create tabletb_'+str_filho+'_'+str_pai+' (id_'+str_filho+' Integer not null, foreignkey (id_'+str_filho+') references tb_'+str_filho+', id_'+str_pai+'Integer not null, foreign key (id_'+str_pai+') references tb_'+str_pai+',primary key (id_'+str_filho+',id_'+str_pai+')',True);

end;//elseend;//else

end;//if modifier='*' or modifier ='+' then

end;//elseend;//else

end;//if pcdata <>'' thenend//if elemento.Items[y].Pai.Filho.Count = 0 thenelsebegin

if elemento.Items[y].Pai.Filho.Count > 0 then

86

beginmodifier_aux:=

Trim(elemento.Items[y].Pai.Modifier);cont_pai:= getNumeroPai(str_filho);if (((modifier ='*') or (modifier='+')) and

((modifier_aux='*') or (modifier_aux='+'))) thenbegin

if cont_pai = 1 thenbegin

//cria uma tabela para o filho com oid do pai

ValueListEditorTb.InsertRow('tb_'+str_filho,'create tabletb_'+str_filho+' (id_'+str_filho+' Integer not null, primary key(id_'+str_filho+'), id_'+str_pai+' Integer not null, foreign key(id_'+str_pai+') references tb_'+str_pai,True);

if possuiAtributos(str_filho) thenaddAtributosElemento(str_filho);

end//if cont_pai = 1 thenelsebegin

//cria uma tabela p/ guardar o id dopai e o id do filho

ValueListEditorTb.InsertRow('tb_'+str_filho+'_'+str_pai,'create tabletb_'+str_filho+'_'+str_pai+' (id_'+str_filho+' Integer not null, foreignkey (id_'+str_filho+') references tb_'+str_filho+', id_'+str_pai+'Integer not null, foreign key (id_'+str_pai+') references tb_'+str_pai+',primary key(id_'+str_filho+',id_'+str_pai+')',True);

achou:=False;if getKeyTb('tb_'+str_filho) > 0 thenbegin

achou:=True;end;//if getKeyTb('tb_'+str_filho) >

0 thenif not achou thenbegin

//cria uma tabela p/ o filho

ValueListEditorTb.InsertRow('tb_'+str_filho,'create tabletb_'+str_filho+' (id_'+str_filho+' Integer not null, primary key(id_'+str_filho+')',True);

if possuiAtributos(str_filho)then

addAtributosElemento(str_filho);end;//if achou=False then

end;//elseend;//if (modifier ='*' or modifier='+') and

(modifier_aux='*' or modifier_aux='+') thenif (((modifier ='') or (modifier='?')) and

((modifier_aux='*') or (modifier_aux='+'))) thenbegin

if cont_pai = 1 thenbegin

//cria uma tabela para o filho com oid do pai

ValueListEditorTb.InsertRow('tb_'+str_filho,'create table

87

tb_'+str_filho+' (id_'+str_filho+' Integer not null, primary key(id_'+str_filho+'), id_'+str_pai+' Integer not null, foreign key(id_'+str_pai+') references tb_'+str_pai,True);

if possuiAtributos(str_filho)thenaddAtributosElemento(str_filho);

end//if cont_pai = 1 thenelsebegin

//cria uma tabela p/ guardar o id dopai e o id do filho

ValueListEditorTb.InsertRow('tb_'+str_filho+'_'+str_pai,'create tabletb_'+str_filho+'_'+str_pai+' (id_'+str_filho+' Integer not null, foreignkey (id_'+str_filho+') references tb_'+str_filho+', id_'+str_pai+'Integer not null, foreign key (id_'+str_pai+') references tb_'+str_pai+',primary key (id_'+str_filho+',id_'+str_pai+')',True);

achou:=False;if getKeyTb('tb_'+str_filho) > 0 thenbegin

achou:=True;end;//if getKeyTb('tb_'+str_filho) >

0 thenif not achou thenbegin

//cria uma tabela par o filho

ValueListEditorTb.InsertRow('tb_'+str_filho,'create tabletb_'+str_filho+' (id_'+str_filho+' Integer not null, primary key(id_'+str_filho+')',True);

if possuiAtributos(str_filho)then

addAtributosElemento(str_filho);end;//if achou=False then

end;//elseend;//if (modifier ='' or modifier='?') and

(modifier_aux='*' or modifier_aux='+') thenif (((modifier ='*') or (modifier='+')) and

((modifier_aux=''))) thenbegin

if cont_pai = 1 thenbegin

//cria uma tabela para o filho com oid do pai

ValueListEditorTb.InsertRow('tb_'+str_filho,'create tabletb_'+str_filho+' (id_'+str_filho+' Integer not null, primary key(id_'+str_filho+'), id_'+str_pai+' Integer not null, foreign key(id_'+str_pai+') references tb_'+str_pai,True);

if possuiAtributos(str_filho) thenaddAtributosElemento(str_filho);

end//if cont_pai = 1 thenelsebegin

//cria uma tabela para o filhoachou:=False;if getKeyTb('tb_'+str_filho) > 0 thenbegin

achou:=True;

88

end;//if getKeyTb('tb_'+str_filho) >0 then

if not achou thenbegin

ValueListEditorTb.InsertRow('tb_'+str_filho,'create tabletb_'+str_filho+' (id_'+str_filho+' Integer not null, primary key(id_'+str_filho+')',True);

if possuiAtributos(str_filho)then

addAtributosElemento(str_filho);end;//if achou then//cria uma tabela auxilara com o id

do filho e o id da tabela pai

ValueListEditorTb.InsertRow('tb_'+str_filho+'_'+str_pai,'create tabletb_'+str_filho+'_'+str_pai+' (id_'+str_filho+' Integer not null, foreignkey (id_'+str_filho+') references tb_'+str_filho+', id_'+str_pai+'Integer not null, foreign key (id_'+str_pai+') references tb_'+str_pai+',primary key (id_'+str_filho+',id_'+str_pai+')',True);

end;//elseend;//if ((modifier ='*') or (modifier='+'))

and ((modifier_aux='')) then

if ((modifier ='') or (modifier='?') and(modifier_aux='')) then

beginif (modifier_pai = '*') or (modifier_pai

= '+') thenbegin

if cont_pai = 1 thenbegin

//cria uma taebla para o filhocom o id do pai

ValueListEditorTb.InsertRow('tb_'+str_filho,'create tabletb_'+str_filho+' (id_'+str_filho+' Integer not null, primary key(id_'+str_filho+'),' +'id_'+str_pai+' Integer not null, foreign key(id_'+str_pai+') references tb_'+str_pai,True);

if possuiAtributos(str_filho)then

addAtributosElemento(str_filho);end//if cont_pai = 1 thenelsebegin

//cria uma tabela para o filhoachou:=False;if getKeyTb('tb_'+str_filho) > 0

thenbegin

achou:=True;end;//if

getKeyTb('tb_'+str_filho) > 0 thenif not achou thenbegin

ValueListEditorTb.InsertRow('tb_'+str_filho,'create table

89

tb_'+str_filho+' (id_'+str_filho+' Integer not null, primary key(id_'+str_filho+')',True);

if possuiAtributos(str_filho)then

addAtributosElemento(str_filho);end;//if achou then//cria uma tabela auxiliar com o

id filho e o id do pai

ValueListEditorTb.InsertRow('tb_'+str_filho+'_'+str_pai,'create tabletb_'+str_filho+'_'+str_pai+' (id_'+str_filho+' Integer not null, foreignkey (id_'+str_filho+') references tb_'+str_filho+', id_'+str_pai+'Integer not null, foreign key (id_'+str_pai+') references tb_'+str_pai+',primary key (id_'+str_filho+',id_'+str_pai+')',True);

end;//elseend//if (modifier_pai = '*') or

(modifier_pai = '+') thenelsebegin

if notpossuiSoFilhosMultivalorados(str_filho) then

begin//adiciona o id do filho na

tabela paiachou:=False;if getKeyTb('tb_'+str_pai) > 0

thenbegin

pos_tb:=getKeyTb('tb_'+str_pai);key_tb:='tb_'+str_pai;achou:=True;

end;//if getKeyTb('tb_'+str_pai)> 0 then

if not achou thenbegin

//cria uma tabela para o pai

ValueListEditorTb.InsertRow('tb_'+str_pai,'create table tb_'+str_pai+'(id_'+str_pai+' Integer not null, primary key (id_'+str_pai+')',True);

if possuiAtributos(str_pai)then

addAtributosElemento(str_pai);

if getKeyTb('tb_'+str_pai) >0 then

begin

pos_tb:=getKeyTb('tb_'+str_pai);key_tb:='tb_'+str_pai;

end;//ifgetKeyTb('tb_'+str_pai) > 0 then

end;//if achou=False then//adiciona o id do filho na

tabela paiif modifier <>'?' thenbegin

90

ValueListEditorTb.InsertRow(ValueListEditorTb.Keys[pos_tb],

ValueListEditorTb.Values[key_tb]+', '+'id_'+str_filho+' Integer not null,foreign key (id_'+str_filho+') references tb_'+str_filho,True);

ValueListEditorTb.DeleteRow(pos_tb);end//if modifier ='' thenelsebegin

ValueListEditorTb.InsertRow(ValueListEditorTb.Keys[pos_tb],

ValueListEditorTb.Values[key_tb]+', '+'id_'+str_filho+' Integer, foreignkey (id_'+str_filho+') references tb_'+str_filho,True);

ValueListEditorTb.DeleteRow(pos_tb);end;//else

end//if notpossuiSoFilhosMultivalorados(str_filho) then

elsebegin

//cria uma tabela para o filhocom o id do pai

ValueListEditorTb.InsertRow('tb_'+str_filho,'create tabletb_'+str_filho+' (id_'+str_filho+' Integer not null, primary key(id_'+str_filho+'), id_'+str_pai+' Integer not null, foreign key(id_'+str_pai+') references tb_'+str_pai,True);

if possuiAtributos(str_filho)then

addAtributosElemento(str_filho);end;//esle

end;//elseend;//if ((modifier ='') or (modifier='?'))

and ((modifier_aux='')) thenend;//if elemento.Items[y].Pai.Filho.Count > 0

thenend;//else//elemeneto vazioif tipo = 'EMPTY' thenbegin

if (modifier ='') or (modifier='?') thenbegin

if (modifier_pai = '*') or (modifier_pai ='+') then

begin//cria uma tabela com o id do pai

ValueListEditorTb.InsertRow('tb_'+str_filho+'_'+str_pai,'create tabletb_'+str_filho+'_'+str_pai+' (id_'+str_filho+' Integer not null, primarykey (id_'+str_filho+'),' +'id_'+str_pai+' Integer not null, foreign key(id_'+str_pai+') references tb_'+str_pai,True);

if possuiAtributos(str_filho) then

addAtributosElemMisto(str_filho,str_pai);end//if (modifier_pai = '*') or (modifier_pai

= '+') then

91

elsebegin

//cria uma tabela para o elemento vazioachou:=False;if getKeyTb('tb_'+str_filho) > 0 thenbegin

achou:=True;end;//if getKeyTb('tb_'+str_filho) > 0

thenif not achou thenbegin

//cria uma tabela para o filho

ValueListEditorTb.InsertRow('tb_'+str_filho,'create tabletb_'+str_filho+' (id_'+str_filho+' Integer not null, primary key(id_'+str_filho+')',True);

if possuiAtributos(str_filho) thenbegin

addAtributosElemento(str_filho);end;//if possuiAtributos(str_filho) =

True thenend;//if achou=False then//adiciona o id do filho na tabela paiachou:=False;if getKeyTb('tb_'+str_pai) > 0 thenbegin

pos_tb:=getKeyTb('tb_'+str_pai);key_tb:='tb_'+str_pai;achou:=True;

end;//if getKeyTb('tb_'+str_pai) > 0 thenif not achou thenbegin

//cria uma tabela p/ pai

ValueListEditorTb.InsertRow('tb_'+str_pai,'create table tb_'+str_pai+'(id_'+str_pai+' Integer not null, primary key (id_'+str_pai+')',True);

if possuiAtributos(str_filho) thenbegin

addAtributosElemento(str_filho);end;//if possuiAtributos(str_filho) =

True thenif getKeyTb('tb_'+str_pai) > 0 thenbegin

pos_tb:=getKeyTb('tb_'+str_pai);key_tb:='tb_'+str_pai;

end;//if getKeyTb('tb_'+str_pai) > 0then

end;//if achou=False then//adiciona o id do filho na tabela do paiif modifier<>'?'thenbegin

ValueListEditorTb.InsertRow(ValueListEditorTb.Keys[pos_tb],ValueListEditorTb.Values[key_tb]+',

'+'id_'+str_filho+' Integer not null, foreign key (id_'+str_filho+')references tb_'+str_filho,True);

ValueListEditorTb.DeleteRow(pos_tb);end//if modifier=''thenelse

92

begin

ValueListEditorTb.InsertRow(ValueListEditorTb.Keys[pos_tb],ValueListEditorTb.Values[key_tb]+',

'+'id_'+str_filho+' Integer, foreign key (id_'+str_filho+') referencestb_'+str_filho,True);

ValueListEditorTb.DeleteRow(pos_tb);end;//else

end;//elseend//if (modifier ='') or (modifier='?') thenelsebegin

if (modifier ='*') or (modifier='+') thenbegin

//cria uma tabela para o elemento vazioachou:=False;if getKeyTb('tb_'+str_filho) > 0 thenbegin

achou:=True;end;//if getKeyTb('tb_'+str_filho) > 0

thenif not achou thenbegin

//cria uma tabela para o filho

ValueListEditorTb.InsertRow('tb_'+str_filho,'create tabletb_'+str_filho+' (id_'+str_filho+' Integer not null, primary key(id_'+str_filho+')',True);

//inserir atributosif possuiAtributos(str_filho) thenbegin

addAtributosElemento(str_filho);end;//if possuiAtributos(str_filho) =

True thenend;//if achou=False then//cria uma tabela auxiliar com o id do

filho e do pai

ValueListEditorTb.InsertRow('tb_'+str_filho+'_'+str_pai,'create tabletb_'+str_filho+'_'+str_pai+' (id_'+str_filho+' Integer not null, foreignkey (id_'+str_filho+') references tb_'+str_filho+', id_'+str_pai+'Integer not null, foreign key (id_'+str_pai+') references tb_'+str_pai+',primary key (id_'+str_filho+',id_'+str_pai+')',True);

end;//if (modifier ='*') or (modifier='+')then

end;//else

end;//if tipo <> '' then//elemento mistoif elemento.Items[y].Pai.Misto.Count > 0 thenbegin

//cria uma tabela para o filho com o id do pai

ValueListEditorTb.InsertRow('tb_'+str_filho+'_'+str_pai,'create tabletb_'+str_filho+'_'+str_pai+' (id_'+str_filho+' Integer not null, primarykey (id_'+str_filho+'), id_'+str_pai+' Integer not null, foreign key(id_'+str_pai+') references tb_'+str_pai,True);

if possuiAtributos(str_filho) thenaddAtributosElemMisto(str_filho,str_pai);

93

for aux_misto:=0 to elemento.Items[y].Pai.Misto.Count-1 do

begin

str_nome_misto:=Trim(elemento.Items[y].Pai.Misto.Nome[aux_misto]);cont_pai:=getNumeroPai(str_nome_misto);if str_nome_misto='PCDATA' thenbegin

if cont_pai = 1 thenbegin

//cria um tabela para o elemento mistocom o id de seu pai

ValueListEditorTb.InsertRow('tb_PCDATA','create table tb_pcdata(id_pcdata Integer not null, primary key (id_pcdata), id_'+str_filho+'Integer not null, foreign key (id_'+str_filho+') referencestb_'+str_filho+'_'+str_pai+', PCDATA nvarchar(250) not null',True);

end//if cont_pai = 1 thenelsebegin

achou:=False;if getKeyTb('tb_PCDATA') > 0 thenbegin

achou:=True;end;//if getKeyTb('tb_PCDATA') > 0 thenif not achou thenbegin

//cria uma tabela para o elementomisto

ValueListEditorTb.InsertRow('tb_PCDATA','create table tb_pcdata(id_pcdata Integer not null, primary key (id_pcdata), PCDATAnvarchar(250) not null',True);

end;//if achou=False then//cria uma tabela com o id elemento

misto, do pai e do avô

ValueListEditorTb.InsertRow('tb_'+str_filho+'_'+str_pai+'_PCDATA','createtable tb_'+str_filho+'_'+str_pai+'_PCDATA (id_pcdata Integer not null,foreign key (id_pcdata) references tb_pcdata, id_'+str_filho+' Integernot null, foreign key (id_'+str_filho+') referencestb_'+str_filho+'_'+str_pai,True);

end;//elseend//if str_nome_misto='PCDATA' thenelsebegin

for aux:=1 to elemento.Count - 1 dobegin

if Trim(elemento.Items[aux].Pai.Nome) =str_nome_misto then

begin

pcdata_misto:=Trim(elemento.Items[aux].Pai.Pcdata);

tipo_misto:=Trim(elemento.Items[aux].Pai.Tipo);if

elemento.Items[aux].Pai.Filho.Count > 0 thenbegin

if cont_pai = 1 then

94

begin//cria uma tabela para o

elemento misto com o id de seu pai

ValueListEditorTb.InsertRow('tb_'+str_nome_misto,'create tabletb_'+str_nome_misto+'(id_'+str_nome_misto+' Integer not null, primary key(id_'+str_nome_misto+'), id_'+str_filho+' Integer not null, foreign key(id_'+str_filho+') references tb_'+str_filho+'_'+str_pai,True);

ifpossuiAtributos(str_nome_misto) then

addAtributosElemento(str_nome_misto);end// if cont_pai = 1 thenelsebegin

if cont_pai > 1 thenbegin

achou:=False;if

getKeyTb('tb_'+str_nome_misto) > 0 thenbegin

achou:=True;end;//if

getKeyTb('tb_'+str_nome_misto) > 0 thenif achou=False thenbegin

//cria uma tabelapara o elemento misto

ValueListEditorTb.InsertRow('tb_'+str_nome_misto,'create tabletb_'+str_nome_misto+' (id_'+str_nome_misto+' Integer not null, primarykey (id_'+str_nome_misto+')',True);

ifpossuiAtributos(str_nome_misto) then

addAtributosElemento(str_nome_misto);end;//if achou=False then//cria uma tabela

auxiliar com o id do elemento misto, id do pai

ValueListEditorTb.InsertRow('tb_'+str_filho+'_'+str_pai+'_'+str_nome_misto,'create table tb_'+str_filho+'_'+str_pai+'_'+str_nome_misto+'(id_'+str_nome_misto+' Integer not null, foreign key(id_'+str_nome_misto+') references tb_'+str_nome_misto+',id_'+str_filho+' Integer not null, foreign key (id_'+str_filho+')references tb_'+str_filho+'_'+str_pai+', primary key(id_'+str_nome_misto+')',True);

end;//if cont_pai > 1 thenend;//else

end//ifelemento.Items[aux].Pai.Filho.Count > 0 then

elsebegin

ifelemento.Items[aux].Pai.Filho.Count = 0 then

begin//cria um tabela para o

elemento e adiciona o id do pai

95

if pcdata_misto = 'PCDATA'then

beginif cont_pai = 1 thenbegin

//cria uma tabelapara o elemento misto, id do pai e o id de seu avô

ValueListEditorTb.InsertRow('tb_'+str_nome_misto,'create tabletb_'+str_nome_misto+' (id_'+str_nome_misto+' Integer not null, primarykey (id_'+str_nome_misto+'), '+'id_'+str_filho+' Integer not null,foreign key (id_'+str_filho+') references tb_'+str_filho+'_'+str_pai+','+str_nome_misto+' nvarchar(250) not null',True);

ifpossuiAtributos(str_nome_misto) then

addAtributosElemento(str_nome_misto);end//if cont_pai = 1

thenelsebegin

if cont_pai > 1then

beginachou:=False;if

getKeyTb('tb_'+str_nome_misto) > 0 thenbegin

achou:=True;end;//if

getKeyTb('tb_'+str_nome_misto) > 0 thenif achou=False

thenbegin

//cria umatabela para o elemento misto

ValueListEditorTb.InsertRow('tb_'+str_nome_misto,'create tabletb_'+str_nome_misto+' (id_'+str_nome_misto+' Integer not null, primarykey (id_'+str_nome_misto+'),'+str_nome_misto+' nvarchar(250) notnull',True);

ifpossuiAtributos(str_nome_misto) then

addAtributosElemento(str_nome_misto);end;//if

achou=False then//cria uma

tabela auxiliar com o id do elemento misto, id do pai

ValueListEditorTb.InsertRow('tb_'+str_filho+'_'+str_pai+'_'+str_nome_misto,'create table tb_'+str_filho+'_'+str_pai+'_'+str_nome_misto+'(id_'+str_nome_misto+' Integer not null, foreign key(id_'+str_nome_misto+') references tb_'+str_nome_misto+',id_'+str_filho+' Integer not null, foreign key (id_'+str_filho+')references tb_'+str_filho+'_'+str_pai+', primary key(id_'+str_nome_misto+')',True);

96

end;//if cont_pai >1 then

end;//elseend//if pcdata_misto =

'PCDATA' thenelsebegin

if tipo_misto = 'EMPTY'then

beginif (cont_pai = 1)

and (getNumeroPai(str_filho)=1) thenbegin

//cria umatabela para o elemento misto, id do pai

ValueListEditorTb.InsertRow('tb_'+str_nome_misto,'create tabletb_'+str_nome_misto+' (id_'+str_nome_misto+' Integer not null, primarykey (id_'+str_nome_misto+'), '+'id_'+str_filho+' Integer not null,foreign key (id_'+str_filho+') references tb_'+str_filho+'_'+str_pai+','+str_nome_misto+' nvarchar(250) not null',True);

//atribui osatributos na tabela

ifpossuiAtributos(str_nome_misto) = True then

addAtributosElemento(str_nome_misto);

//addAtributosElemento(str_nome_misto);end//if cont_pai =

1 thenelsebegin

if (cont_pai >1) or (getNumeroPai(str_filho)>1) then

begin

achou:=False;if

getKeyTb('tb_'+str_nome_misto) > 0 thenbegin

achou:=True;end;//if

getKeyTb('tb_'+str_nome_misto) > 0 thenif

achou=False thenbegin

//criauma tabela para o elemento misto

ValueListEditorTb.InsertRow('tb_'+str_nome_misto,'create tabletb_'+str_nome_misto+' (id_'+str_nome_misto+' Integer not null, primarykey (id_'+str_nome_misto+'),'+str_nome_misto,True);

ifpossuiAtributos(str_nome_misto) = True then

addAtributosElemento(str_nome_misto);

97

end;//ifachou=False then

//cria umatabela auxiliar com o id do elemento misto, id do pai

ValueListEditorTb.InsertRow('tb_'+str_filho+'_'+str_pai+'_'+str_nome_misto,'create table tb_'+str_filho+'_'+str_pai+'_'+str_nome_misto+'(id_'+str_nome_misto+' Integer not null, foreign key(id_'+str_nome_misto+') references tb_'+str_nome_misto+',id_'+str_filho+' Integer not null, foreign key (id_'+str_filho+')references tb_'+str_filho+'_'+str_pai+', primary key(id_'+str_nome_misto+')',True);

end;//ifcont_pai > 1 then

end;//elseend;//if tipo_misto =

'EMPTY' thenend;//else

end;//ifelemento.Items[aux].Pai.Filho.Count = 0 then

end;//elseend;//if

Trim(elemento.Items[aux].Pai.Nome) = str_nome_misto thenend;//for aux:=1 to elemento.Count - 1 do

end;//else

end;//for aux_misto:=0 toelemento.Items[y].Pai.Misto.Count -1 do

end;//if elemento.Items[y].Pai.Misto.Count > 0 theny:= elemento.Count;

end;//if Trim(elemento.Items[y].Pai.Nome)=str_filho theny:= y+1;

end;//while y < elemento.Count doend;//for i:=0 to elemento.Items[j].Pai.Filho.Count -1 do

end;//for j:=0 to elemento.Count -1 doend;

procedure TForm_principal.AbrirClick(Sender: TObject);begin

fileAbrir();end;

procedure TForm_principal.SalvarClick(Sender: TObject);begin

fileSave();end;

procedure TForm_principal.SairClick(Sender: TObject);begin

Close;end;

procedure TForm_principal.DTDMRClick(Sender: TObject);var i:Integer;

beginValueListEditorTb.Strings.Clear;algoritmo();RichEdit.Clear;

98

RichEdit.Lines.Add('create database'+Trim(elemento.Items[0].Pai.Nome));

for i:=1 to ValueListEditorTb.RowCount - 1 dobegin

RichEdit.Lines.Add('');

RichEdit.Lines.Add(Trim(ValueListEditorTb.Values[ValueListEditorTb.Keys[i]])+');');

end;DTDMR.Enabled:=False;SB_mapeador.Enabled:=False;Label_tab.Caption:='Modelo Relacional Gerado a partir do DTD.';

end;

procedure TForm_principal.SB_abrirClick(Sender: TObject);begin

fileAbrir();end;

procedure TForm_principal.SP_salvarClick(Sender: TObject);begin

fileSave();end;

procedure TForm_principal.SB_mapeadorClick(Sender: TObject);var i:Integer;

beginValueListEditorTb.Strings.Clear;algoritmo();RichEdit.Clear;RichEdit.Lines.Add('create database

'+Trim(elemento.Items[0].Pai.Nome));for i:=1 to ValueListEditorTb.RowCount - 1 dobegin

RichEdit.Lines.Add('');

RichEdit.Lines.Add(Trim(ValueListEditorTb.Values[ValueListEditorTb.Keys[i]])+');');

end;Label_tab.Caption:='Modelo Relacional Gerado a partir do DTD.';

end;

procedure TForm_principal.SB_limparClick(Sender: TObject);begin

Label_tab.Caption:='Mapeador de DTD/Modelo Relacional';RichEdit.Clear;ValueListEditorTb.Strings.Clear;

end;

procedure TForm_principal.SB_sairClick(Sender: TObject);begin

Close;end;

procedure TForm_principal.LimparClick(Sender: TObject);begin

Label_tab.Caption:='Mapeador de DTD/Modelo Relacional';RichEdit.Clear;ValueListEditorTb.Strings.Clear;

99

end;

procedure TForm_principal.FonteClick(Sender: TObject);begin

if FontDialog.Execute thenbegin

tryRichEdit.Font.Color:=FontDialog.Font.Color;RichEdit.Font.Size:=FontDialog.Font.Size;RichEdit.Font.Style:=FontDialog.Font.Style;

ExceptShowMessage('Não foi possui alterar a fonte');

end;end;

end;

procedure TForm_principal.SB_fontClick(Sender: TObject);begin

if FontDialog.Execute thenbegin

tryRichEdit.Font.Color:=FontDialog.Font.Color;RichEdit.Font.Size:=FontDialog.Font.Size;RichEdit.Font:=FontDialog.Font;

ExceptShowMessage('Não foi possui alterar a fonte');

end;end;

end;

procedure TForm_principal.SpeedButton1Click(Sender: TObject);var contPrint: Integer;

begintry

if PrintDialog.Execute thenbegin

for contPrint:=1 to PrintDialog.Copies doRichEdit.Print(RichEdit.Lines.Text);

end;Except

ShowMessage('Não existe impressora instalada!');end;

end;

procedure TForm_principal.Imprimir1Click(Sender: TObject);var contPrint: Integer;

begintry

if PrintDialog.Execute thenbegin

for contPrint:=1 to PrintDialog.Copies doRichEdit.Print(RichEdit.Lines.Text);

end;Except

ShowMessage('Não existe impressora instalada!');end;

end;

100

end.