Back to TILs

Eclipse Modeling Framework - Lendo e escrevendo XML

Date: 2019-12-05Last modified: 2022-10-07

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:

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:

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

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

Use a API Resource.save(...)

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

<myRootElement xmlns="http://example.com/myXml" someAttribute="value">
   <myAnotherElement anotherAttribute="value 2"/>
</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.

<myRootElement someAttribute="value">
   <myAnotherElement anotherAttribute="value 2"/>
</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.

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

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:

Map<String, Object> options = new HashMap<String, Object>();
options.put(XMLResource.OPTION_EXTENDED_META_DATA, Boolean.TRUE);
// options.put(XMLResource.OPTION_RECORD_UNKNOWN_FEATURE, Boolean.TRUE);
options.put(XMLResource.OPTION_ENCODING, "UTF-8");

Ver capítulo 13 do livro

Referências