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=”…”>
)
<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");
OPTION_EXTENDED_META_DATA
- cria elementos aninhados em vez de atributos. Não estou certo se isto influencia no carregamentoOPTION_RECORD_UNKNOWN_FEATURE
- quando um elemento desconhecido for encontrado no carregamento não será lançada uma exceção deunknown feature
e o campo será apenas puladoOPTION_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