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つあります。

  1. XSDEcoreBuilder.generateResources()を使ってXMLスキーマからEMFモデルを動的生成する
  2. 動的生成された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);