Publicado em: 05/Dec/2019
Atualizado em: 16/Dec/2019
EMF
XML

Eclipse Modeling Framework - Lendo e escrevendo XML

EMF é uma API Java que permite definir modelos, criar, salvar e carregar suas instâncias em vários formatos (EMF, UML, XSD).

A principal diferença para o Java é que os modelos podem ser definidos tanto estaticamente quanto dinamicamente em tempo de execução.

EMF suporta múltiplos formatos para o modelo e para input e output das intâncias do modelo.

EMF é uma API do tipo reflection e pode ser facilmente utilizada para gerar editores para seus modelos.

O meta-modelo para definição do modelo consiste dos seguintes elementos:

  • EClass
  • EAttribute
  • EOperation
  • etc

Estes elementos são agrupados em EPackages identificados unicamente por uma URI de namespace que pode ser conhecida através do XSD.

Instâncias do modelo são compostas de EObjects (e classes de suporte como EList).

Cada um destes elementos é representado por uma classe Java.

Configuração do EMF e namespace

Existem três opções:

  • namespace com prefixo explícito
  • namespace sem prefixo (declarado como padrão)
  • sem namespace

Elemento raiz do XML no namespace com prefixo (xmlns:ns=”…”>)

1<myRootElement xmlns:ns="http://example.com/myXml" someAttribute="value">
2   <myAnotherElement anotherAttribute="value 2"/>
3<myRootElement>

Use a API Resource.save(...)

Elemento raiz do XML no namespace padrão (<elm xmlns=”…”>)

1<myRootElement xmlns="http://example.com/myXml" someAttribute="value">
2   <myAnotherElement anotherAttribute="value 2"/>
3</myRootElement>

Veja esta dica

Nenhuma informação sobre namespace no the XML (<elm>)

Este é o pior caso pois o XML de entrada não se descreve suficientemente e você precisa conhecer ou chutar o EPackage correto para realizar o parser.

Certamente seria melhor se você tivesse informação do namespace. Mas algumas vezes você não terá como influenciar a entrada a ser lida com o EMF.

1<myRootElement someAttribute="value">
2   <myAnotherElement anotherAttribute="value 2"/>
3</myRootElement>

Se o elemento raiz do XML não possuir prefixo nem namespace então o EMF não será capaz de realizar o match com o EPackage e consequentemente não será capaz de carregar apropriadamente a menos que você registre um EPackage alvo com o ResourceSet global com uma URI nula.

1for (EPackage ePackage: eCorePackages) {
2	resourceSet.getPackageRegistry().put(null, ePackage);
3	// alternatively could call EPackage.Registry.INSTANCE.put(..)
4}

De acordo com a dica do forum você não pode injetar a declaração faltante do XMLNS no XML, mas pode especificar null para o namespace e o pacote específico para mapear usando o pacote de registro do ResourceSet.

Notas gerais sobre salvar e carregar XML pelo EMF

Quando carregar do XML ou salvar para o XML você precisa passar algumas das seguintes opções para os métodos save ou load:

1Map<String, Object> options = new HashMap<String, Object>();
2options.put(XMLResource.OPTION_EXTENDED_META_DATA, Boolean.TRUE);
3// options.put(XMLResource.OPTION_RECORD_UNKNOWN_FEATURE, Boolean.TRUE);
4options.put(XMLResource.OPTION_ENCODING, "UTF-8");
  • OPTION_EXTENDED_META_DATA - cria elementos aninhados em vez de atributos. Não estou certo se isto influencia no carregamento
  • OPTION_RECORD_UNKNOWN_FEATURE - quando um elemento desconhecido for encontrado no carregamento não será lançada uma exceção de unknown feature e o campo será apenas pulado
  • OPTION_ENCODING – é o encoding para geração do XML, onde o padrão é ASCII. Não estou certo se isto influencia no carregamento

Ver capítulo 13 do livro

Referências

comments powered by Disqus