XMLスキーマから動的生成したEMFモデルのインスタンスをxsi:schemaLocation付きで直列化する
以下のサイトに、XMLスキーマから動的にEMFモデルを生成する方法や、xsi:schemaLocationが含まれるXML文書をEMFでロードする方法が紹介されています。
EMF/Generating Dynamic Ecore from XML Schema - Eclipsepedia
しかし、XMLスキーマから動的に生成したEMFモデルを使って、そのインスタンスを作成しファイルに直列化(永続化)する際に、後でそのファイルをEMFでロード可能にするためには、xsi:schemaLocation付きで直列化する必要がありますが、その方法は書かれていません。今日はその方法を以下に紹介します。
なお、この方法は、EMF Newsgroupに問い合わせ、Ed Merks氏にご教示いただきました。この場をお借りしてお礼申し上げます。(日本語でごめんなさい。もちろん、Newsgroup上でお礼済みですが)
XMLスキーマから動的生成したEMFモデルのインスタンスをxsi:schemaLocation付きで直列化するためのポイントは大きく2つあります。
- XSDEcoreBuilder.generateResources()を使ってXMLスキーマからEMFモデルを動的生成する
- 動的生成されたEMFモデルのEPackage.eResource()のURIとして、上記XMLスキーマのURIをセットする
以下、サンプルコードです。
XSDEcoreBuilder xsdEcoreBuilder = new XSDEcoreBuilder(); Collection<Resource> resources = xsdEcoreBuilder.generateResources(schemaURI); EPackage ePackage = null; for (Resource resource : resources) { if (resource instanceof XSDResourceImpl) { // schemaURI = resource.getURI(); } else { ePackage = (EPackage) resource.getContents().get(0); } } EObject documentRoot = EcoreUtil.create((EClass) ePackage.getEClassifier("DocumentRoot")); ResourceSet resourceSet = ePackage.eResource().getResourceSet(); Resource resource = resourceSet.createResource( URI.createURI("platform:/resource/project/sample.xml")); resource.getContents().add(documentRoot); ePackage.eResource().setURI(schemaURI); Map<Object, Object> saveOptions = new HashMap<Object, Object>(1); saveOptions.put( XMLResource.OPTION_SCHEMA_LOCATION, Boolean.TRUE); resource.save(saveOptions);