Как использовать EMF для чтения XML-файла? - PullRequest
8 голосов
/ 30 марта 2010

EMF = Eclipse Modeling Framework

Мне нужно использовать EMF в одном из моих проектов. Я пытаюсь понять, как использовать EMF для следующих действий:

  1. Чтение XML,
  2. Получить значения в объекты.
  3. Используйте ORM для сохранения значений в объектах в базе данных. - Готово
  4. Получение данных из базы данных с использованием ORM и генерация XML.

Мне нужно сделать все это, используя: EMF (понятия не имею) и JPA (DONE).

Я использовал JAXB и знаю, что это можно сделать с помощью JAXB, но как (EMF == JAXB)?!

Я создал много классов Java с использованием EMF, но их так много! Где я могу реализовать методы чтения / записи и как запустить проект EMF?

Спасибо

Update1 ПОДСКАЗКА http://www.eclipsezone.com/eclipse/forums/t58829.html

UPDATE2

У меня есть схема, и я сгенерировал код модели, используя .xsd. Теперь у меня проблема с чтением данных из файла XML.

Ответы [ 5 ]

14 голосов
/ 07 февраля 2011

Вы можете читать произвольные файлы XML с помощью EMF, если у вас есть XSD для них, и вам даже не нужно генерировать классы Java из XSD. Я писал об этом пару месяцев назад, но здесь я также буду вставлять фрагменты кода. Чуть более подробное объяснение см. В моем блоге Как загрузить и сравнить произвольные файлы XML с EMF .

Сначала вам нужно загрузить XSD и инициализировать пару вещей:

// generate EPackages from schemas
XSDEcoreBuilder xsdEcoreBuilder = new XSDEcoreBuilder();
Collection generatedPackages = xsdEcoreBuilder.generate(schemaURI);

// register the packages loaded from XSD
for (EObject generatedEObject : generatedPackages) {
    if (generatedEObject instanceof EPackage) {
        EPackage generatedPackage = (EPackage) generatedEObject;
        EPackage.Registry.INSTANCE.put(generatedPackage.getNsURI(),
            generatedPackage);
    }
}

// add file extension to registry
ResourceFactoryRegistryImpl.INSTANCE.getExtensionToFactoryMap()
    .put(MY_FILE_EXTENSION, new GenericXMLResourceFactoryImpl());

После этого вы можете загружать свои XML-файлы, как обычно:

ResourceSet resourceSet = ResourceSetFactory.createResourceSet();
Resource resource = resourceSet.getResource(xmlURI, true);
resource.load(Collections.EMPTY_MAP);
EObject root = resource.getContents().get(0);
4 голосов
/ 06 января 2011

EMF сериализует модель данных, используя (по умолчанию, наиболее популярный способ) XMIResourceImpl, который строго использует формат XMI, а не собственную структуру XML .

См. http://eclipsedriven.blogspot.com/ для статей об ЭДС и ее случаях использования.

Я согласен с другими ответчиками, что EMF, вероятно, не то, что вы хотите здесь.

Если бы я действительно хотел использовать EMF с пользовательской структурой XML (т.е. не XMI), я бы, вероятно, использовал JAXB для маршалирования / демаршалирования моих объектов EMF (EObjects).

Таким образом, ЭМП - это не то же самое, что JAXB, и у них разные цели и задачи. На самом деле вы, вероятно, можете каким-то образом объединить EMF и JAXB. Я никогда не пробовал, но, похоже, есть действительные варианты использования. (как я уже говорил выше, для маршалинга / демаршалирования объектов EMF в / из XML)

Чтобы понять ЭДС, вам нужно изменить свою парадигму. Для начала удалите часть «XML», отпустите ее из головы. Тогда я предлагаю вам сделать следующее:

  1. Создать пустой проект EMF.
  2. Создайте простой файл Ecore (.ecore) или получите его из Интернета. Или импортируйте из любой XML-схемы / UML-файла в модель Ecore.
  3. Щелкните правой кнопкой мыши на EClass, затем «Создать динамический экземпляр», это создаст файл .xmi.
  4. Откройте файл .xmi, используя Eclipse, откроется редактор EMF для этой модели. Отредактируйте, как считаете нужным.
  5. Проверьте содержимое (отредактированного) файла .xmi. Вы увидите, что формат точно соответствует модели Ecore. Вы не сможете изменить / настроить отображение из файла XMI модели <->, поскольку, как следует из названия, XMIResourceImpl только читает / сохраняет файлы XMI (которые реализованы поверх XML), но не читает / сохраняет произвольный формат XML.

EMF поддерживает чтение / запись метамодели XML-схемы (т.е. файлы XSD) с целью преобразования их в метамодель Ecore, но не в файлы XML, соответствующие такой схеме (даже в Ecore) ), если эти файлы не в формате XMI.

Сведения о сохранении моделей EMF в реляционной базе данных см .: http://eclipsedriven.blogspot.com/2010/12/persisting-emf-objects-to-rdbms-with.html

Я использую Teneo. (и, необязательно, CDO)

Что касается "XML", если вы будете придерживаться XMI и будете довольны им, EMF сделает вашу жизнь на намного проще, так как вам не нужно делать любое отображение ( в отличие от JAXB). Недостатком является то, что наши объекты должны быть объектами EMF.

Объекты EMF - это объекты, которые генерируются EMF и реализуют EObject и прямо или косвенно расширяют EObjectImpl. Вы обычно не хотите кодировать объекты EMF вручную, это будет рутинная работа. С другой стороны, «объекты» JAXB обычно являются чисто объектными объектными объектами POJO и не требуют от JAXB дополнительных требований. Обратите внимание, что в отличие от JAXB, объекты EMF не являются POJO. Это объясняет еще одну другую цель между EMF и JAXB. Их перекрытие меньше, чем вы думаете.

Чтение из XMI (не XML) очень просто:

XMIResource resource = new XMIResourceImpl(URI.create("file:/path/to/mymodel.xmi"));
resource.load(null);
System.out.println( resource.eContents().get(0) );
2 голосов
/ 02 мая 2015

Я создал небольшую программу, которая выполняет некоторое базовое преобразование формата модели, используя emftriple (ранее emf4sw), то есть Ecore XMI (файл XML) в RDF TTL.

Я использовал некоторые из советов в ответах здесь, так что спасибо, ребята!

Возможно, исходный код может вдохновить вас: https://github.com/frostyandy2k/model-transformer

1 голос
/ 30 марта 2010

Обычный способ сделать это - начать с схемы XML, затем использовать ее для генерации модели EMF, а затем сгенерировать код Java. Это описано в этом учебнике по ЭМП .

Вам не нужно реализовывать методы чтения / записи. Вместо этого вы используете код библиотеки EMF для импорта и экспорта XML. Прямо сейчас у меня нет моей книги по EMF, но она там описана. Или посмотрите, что делает сгенерированный редактор EMF при загрузке или сохранении экземпляра модели.

РЕДАКТИРОВАТЬ

Вот класс утилиты ресурсов из проекта на основе EMF, который я разработал пару лет назад. Посмотрите на load* методы. Обратите внимание, что это не обязательно лучший способ сделать это ... но это сработало для меня.

РЕДАКТИРОВАТЬ 2

Я только что понял, что использую XMI, а не простой XML. Конфигурирование программы чтения XML с пользовательской схемой и (потенциально) с настроенным отображением схемы, вероятно, будет другим. Итак, возвращаясь к моему первоначальному ответу, посмотрите на сгенерированный код !! .

0 голосов
/ 09 апреля 2010

EMF не предназначен для чтения произвольных файлов XML. EMF использует XML в качестве бэкэнда. Откуда приходят ваши XML-файлы / какой схеме они соответствуют? Если у вас есть схема, вы можете использовать ее для создания модели EMF, которая, в свою очередь, способна читать ваши файлы XML.

В противном случае вам придется перепроектировать модель EMF, которая действительно сериализуется в ваш XML, чтобы вы могли прочитать ее, но это было бы хаком.

После ОБНОВЛЕНИЯ2 :

Наверное, следующий вопрос: «Какая у вас проблема с загрузкой ваших файлов». Как ты это делаешь, а что не работает? Или ты не знаешь как это сделать?

Сначала необходимо настроить фабрику для набора ресурсов (представление набора файлов в памяти, с которым вы хотите работать), а затем загрузить файл с помощью getResource (URI, bool). Пример для некоторых вещей UML, которые я делаю:

resourceSet.getResourceFactoryRegistry().getExtensionToFactoryMap().put(UMLResource.FILE_EXTENSION, UMLResource.Factory.INSTANCE);
resourceSet.getPackageRegistry().put("http://www.eclipse.org/uml2/2.0.0/UML", UMLPackage.eINSTANCE);
Resource r = resourceSet.getResource(uriToYourFile,true);
YourModelRootType root = (YourModelRootType) r.getContents().get(0);

Это должно быть описано в руководстве, на которое у вас уже есть ссылка. Затем вы можете использовать сгенерированный Java API для работы с root'ом.

Хотя у меня нет опыта работы с ORM, но, возможно, вам стоит взглянуть на CDO .

...