Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » EMF » How to manage mixed XSD/XML resource?
How to manage mixed XSD/XML resource? [message #1018859] Thu, 14 March 2013 15:21 Go to next message
Christer Palm is currently offline Christer Palm
Messages: 5
Registered: November 2012
Junior Member
Hi!

I'm using XSDResourceImpl to de-serialize an XML schema based model. The model extends XML schema through <appinfo> XML fragments. As the appinfo fragments are presented by XSDResourceImpl as DOM fragments, I have been post-processing the XSDResources creating an XMLResource for each appinfo fragment to de-serialize it.

Although less than completely elegant, that has worked fine until now.

Now I need to do custom cross-document reference processing for elements within those appinfo fragments. The problem is that the XMLResources I use to de-serialize the appinfo fragments are not members of the ResourceSet, and thus, my custom URIConverter is obviously not called to resolve the references within the appinfo fragments.

So I need to make the fragments members of the ResourceSet in some way and I am trying to figure out the best approach. Would it be best to try to create a custom composite Resource implementation to represent the base XSDResource and the fragment XMLResources as a single Resource?

Does anyone have any ideas or experience with handling XSD appinfo fragments in EMF?

Regards,
Christer Palm
Re: How to manage mixed XSD/XML resource? [message #1018867 is a reply to message #1018859] Thu, 14 March 2013 15:37 Go to previous messageGo to next message
Ed Merks is currently offline Ed Merks
Messages: 26138
Registered: July 2009
Senior Member
Christer,

Comments below.

On 14/03/2013 4:21 PM, Christer Palm wrote:
> Hi!
>
> I'm using XSDResourceImpl to de-serialize an XML schema based model.
> The model extends XML schema through <appinfo> XML fragments. As the
> appinfo fragments are presented by XSDResourceImpl as DOM fragments, I
> have been post-processing the XSDResources creating an XMLResource for
> each appinfo fragment to de-serialize it.
Are you using the ability to deserialize directly from DOM?
>
> Although less than completely elegant, that has worked fine until now.
>
> Now I need to do custom cross-document reference processing for
> elements within those appinfo fragments. The problem is that the
> XMLResources I use to de-serialize the appinfo fragments are not
> members of the ResourceSet, and thus, my custom URIConverter is
> obviously not called to resolve the references within the appinfo
> fragments.
Could you do this under the covers in doLoad, and put the resulting
objects as additional objects in the XSDResourceImpl's getContents()?
>
> So I need to make the fragments members of the ResourceSet in some way
> and I am trying to figure out the best approach. Would it be best to
> try to create a custom composite Resource implementation to represent
> the base XSDResource and the fragment XMLResources as a single Resource?
Maybe you can load the objects move them into the XSD resource?
>
> Does anyone have any ideas or experience with handling XSD appinfo
> fragments in EMF?
>
> Regards,
> Christer Palm
>
Re: How to manage mixed XSD/XML resource? [message #1018904 is a reply to message #1018867] Thu, 14 March 2013 17:00 Go to previous messageGo to next message
Christer Palm is currently offline Christer Palm
Messages: 5
Registered: November 2012
Junior Member
Thanks for the response Ed!

Ed Merks wrote on Thu, 14 March 2013 11:37
Are you using the ability to deserialize directly from DOM?

Yes, exactly.

Quote:
Could you do this under the covers in doLoad, and put the resulting
objects as additional objects in the XSDResourceImpl's getContents()?

That's one of the options I've considered. But the main problem is, when I create the XMLResources to load the DOM fragments, how do I get my XSDResources attached to my ResourceSet so that its URIConverter is called for the cross-document references within the appinfo XML fragments?

And I suppose that problem is twofold;
1. It seems there's no way to create an XMLResource from DOM through the ResourceSet, so I'm just doing "new XMLResourceImpl(uri)" right now, which creates an XMLResource that is not attached to any ResourceSet.
2. What URI would I use for the fragment XMLResources? I assume it has to be unique even though the fragments are actually part of the XSDResource.
Re: How to manage mixed XSD/XML resource? [message #1018910 is a reply to message #1018904] Thu, 14 March 2013 17:10 Go to previous messageGo to next message
Ed Merks is currently offline Ed Merks
Messages: 26138
Registered: July 2009
Senior Member
Christer,

Comments below.

On 14/03/2013 6:00 PM, Christer Palm wrote:
> Thanks for the response Ed!
>
> Ed Merks wrote on Thu, 14 March 2013 11:37
>> Are you using the ability to deserialize directly from DOM?
>
> Yes, exactly.
>
> Quote:
>> Could you do this under the covers in doLoad, and put the resulting
>> objects as additional objects in the XSDResourceImpl's getContents()?
>
> That's one of the options I've considered. But the main problem is,
> when I create the XMLResources to load the DOM fragments, how do I get
> my XSDResources attached to my ResourceSet so that its URIConverter is
> called for the cross-document references within the appinfo XML
> fragments?
Ideally you'd only create proxies during loading. I'm not sure if you
support mutually referencing annotations? Such a thing is only possible
if you defer resolution of the references. I'm not sure how you
identify annotations or what your references look like. I could
imagine each one having a unique name such that you'd use
<schema-uri>#/<name> as the reference to the other annotation and you'd
specialize the root fragment handling to locate the annotations at the
root of the XSD resource.
>
> And I suppose that problem is twofold;
> 1. It seems there's no way to create an XMLResource from DOM through
> the ResourceSet, so I'm just doing "new XMLResourceImpl(uri)" right
> now, which creates an XMLResource that is not attached to any
> ResourceSet.
You can always call ResourceSet.create and load into that...
> 2. What URI would I use for the fragment XMLResources? I assume it has
> to be unique even though the fragments are actually part of the
> XSDResource.
It still seems better they be in the same resource as the XSD. This is
more like what we do with Xcore and the Xtext/Xbase framework. The first
object in the resource is the real physical thing that's loaded and
saved; the remaining objects are derived automatically during loading
and are then accessible as EMF objects in the normal way...

It would be good to understand how you'll identity the things you want
to reference and how you expect the references to look...
Re: How to manage mixed XSD/XML resource? [message #1019080 is a reply to message #1018910] Fri, 15 March 2013 01:59 Go to previous messageGo to next message
Christer Palm is currently offline Christer Palm
Messages: 5
Registered: November 2012
Junior Member
Thanks Ed!

Ed Merks wrote on Thu, 14 March 2013 13:10
Ideally you'd only create proxies during loading. I'm not sure if you
support mutually referencing annotations? Such a thing is only possible
if you defer resolution of the references.

Right. I definitely need deferred resolution, but my impression was that EMF would take care of creating proxies for me as needed. But I'm not there yet and I have no previous experience of custom EMF XML reference resolution so I might be way off there.

Quote:
I'm not sure how you
identify annotations or what your references look like. I could
imagine each one having a unique name such that you'd use
<schema-uri>#/<name> as the reference to the other annotation and you'd
specialize the root fragment handling to locate the annotations at the
root of the XSD resource.

It would be good to understand how you'll identity the things you want
to reference and how you expect the references to look...

The references are W3C XPointer expressions, restricted to shorthand or element scheme syntax. So yes, they're actually very similar to EMF's own href expressions.

I generate the model used insided the appinfo from XSD, so I've enabled href processing by simply adding an ecore annotation to the XSD attribute definition like so:

  <attribute name="href" type="anyURI" ecore:reference="EObject"/>

The plan is then to be able to do whatever needs to be done in the ResourceSet's URIConverter.

The references could more or less target arbitrary XML elements. Either inside an XSDResource (including an element inside an appinfo fragment) or an XMLResource. For XSDResource targets I plan to use XSDSchema#findCorrespondingComponent() to resolve the reference + custom resolution for references to elements inside appinfo. For XMLResource targets I've extended XMLResource with a custom DefaultHandler that tracks the information necessary to resolve the references.

Quote:
You can always call ResourceSet.create and load into that...

Thanks! I thought create() would try to load the resource as well, but I realize now that it doesn't. Duh. I'll try that right away.

Quote:
It still seems better they be in the same resource as the XSD. This is
more like what we do with Xcore and the Xtext/Xbase framework. The first
object in the resource is the real physical thing that's loaded and
saved; the remaining objects are derived automatically during loading
and are then accessible as EMF objects in the normal way...

OK sounds good! Though my issue was rather that if I reuse the URI of the base XSD resource, like I do now, I suppose it would replace the base XSD resource in the ResourceSet. I do need the base part of the URIs to be accurate, because my custom XMLResource relies on it for XML Base processing. But I guess I could just add an URI fragment identifier to keep them unique, like:

file:/x/y/z.xsd <-- URI for the base "physical" XSDResource
file:/x/y/z.xsd#1 <-- URI for the first appinfo fragment XMLResource
file:/x/y/z.xsd#2 <-- URI for the second appinfo fragment XMLResource

Or am I misunderstanding you?

Regards,
Christer Palm
Re: How to manage mixed XSD/XML resource? [message #1019153 is a reply to message #1019080] Fri, 15 March 2013 06:14 Go to previous messageGo to next message
Ed Merks is currently offline Ed Merks
Messages: 26138
Registered: July 2009
Senior Member
Christer,

Comments below.

On 15/03/2013 2:59 AM, Christer Palm wrote:
> Thanks Ed!
>
> Ed Merks wrote on Thu, 14 March 2013 13:10
>> Ideally you'd only create proxies during loading. I'm not sure if
>> you support mutually referencing annotations? Such a thing is only
>> possible if you defer resolution of the references.
>
> Right. I definitely need deferred resolution, but my impression was
> that EMF would take care of creating proxies for me as needed.
Yes, but that's why I'm asking questions about what the references would
look like...
> But I'm not there yet and I have no previous experience of custom EMF
> XML reference resolution so I might be way off there.
The reference will be of the form <URI>#<fragment> and your resource
implementation can control what the fragment looks like...
>
> Quote:
>> I'm not sure how you identify annotations or what your references
>> look like. I could imagine each one having a unique name such that
>> you'd use <schema-uri>#/<name> as the reference to the other
>> annotation and you'd specialize the root fragment handling to locate
>> the annotations at the root of the XSD resource.
>>
>> It would be good to understand how you'll identity the things you
>> want to reference and how you expect the references to look...
>
> The references are W3C XPointer expressions, restricted to shorthand
> or element scheme syntax. So yes, they're actually very similar to
> EMF's own href expressions.
Similar might not be sufficient. Certainly your ResourceImpl.getEObject
must know how to interpret the fragment portion of such a URI.
>
> I generate the model used insided the appinfo from XSD, so I've
> enabled href processing by simply adding an ecore annotation to the
> XSD attribute definition like so:
>
> <attribute name="href" type="anyURI" ecore:reference="EObject"/>
> The plan is then to be able to do whatever needs to be done in the
> ResourceSet's URIConverter.
It's designed to be responsible for mapping the <URI> from logic to
physical locations and for providing the associated streams. The
resource implementations are responsible for producing and consuming the
fragment portion.
>
> The references could more or less target arbitrary XML elements.
> Either inside an XSDResource (including an element inside an appinfo
> fragment) or an XMLResource. For XSDResource targets I plan to use
> XSDSchema#findCorrespondingComponent() to resolve the reference +
> custom resolution for references to elements inside appinfo.
That makes sense.
> For XMLResource targets I've extended XMLResource with a custom
> DefaultHandler that tracks the information necessary to resolve the
> references.
I still get the sense it would be better to keep all the things that
originate from one physical XML (XSD) in a single resource
implementation. A fragment URI syntax that's recognizably different
from the one used to refer only to the XSD portions should allow for that.
>
> Quote:
>> You can always call ResourceSet.create and load into that...
>
> Thanks! I thought create() would try to load the resource as well, but
> I realize now that it doesn't. Duh. I'll try that right away.
>
> Quote:
>> It still seems better they be in the same resource as the XSD. This
>> is more like what we do with Xcore and the Xtext/Xbase framework. The
>> first object in the resource is the real physical thing that's loaded
>> and saved; the remaining objects are derived automatically during
>> loading and are then accessible as EMF objects in the normal way...
>
> OK sounds good! Though my issue was rather that if I reuse the URI of
> the base XSD resource, like I do now, I suppose it would replace the
> base XSD resource in the ResourceSet. I do need the base part of the
> URIs to be accurate, because my custom XMLResource relies on it for
> XML Base processing. But I guess I could just add an URI fragment
> identifier to keep them unique, like:
>
> file:/x/y/z.xsd <-- URI for the base "physical" XSDResource
> file:/x/y/z.xsd#1 <-- URI for the first appinfo fragment XMLResource
> file:/x/y/z.xsd#2 <-- URI for the second appinfo fragment XMLResource
You can't expect the fragment to help identity the resource itself. Of
course the XSDResourceImpl could resolve getEObject to objects in other
resources, Xtext makes heavy use of that to defer the resolution of
scoped names. In the end I get the sense that it's best to make all
this stuff (the objects corresponding to annotations) look like it's
logically contained in a single resource (the XSD's resource).
>
> Or am I misunderstanding you?
>
> Regards,
> Christer Palm
>
Re: How to manage mixed XSD/XML resource? [message #1019274 is a reply to message #1019153] Fri, 15 March 2013 10:56 Go to previous messageGo to next message
Christer Palm is currently offline Christer Palm
Messages: 5
Registered: November 2012
Junior Member
Thanks again Ed for your response!

Ed Merks wrote on Fri, 15 March 2013 02:14
The reference will be of the form <URI>#<fragment> and your resource
implementation can control what the fragment looks like...

OK, that will be perfectly fine.

Quote:
Similar might not be sufficient. Certainly your ResourceImpl.getEObject
must know how to interpret the fragment portion of such a URI.

It's designed to be responsible for mapping the <URI> from logic to
physical locations and for providing the associated streams. The
resource implementations are responsible for producing and consuming the
fragment portion.

OK I see, so the URIConverter won't be involved in resolving the fragment part. I need to look further into Resource#getEObject then, but it it sounds straightforward.

Quote:
I still get the sense it would be better to keep all the things that
originate from one physical XML (XSD) in a single resource
implementation. A fragment URI syntax that's recognizably different
from the one used to refer only to the XSD portions should allow for that.

You can't expect the fragment to help identity the resource itself. Of
course the XSDResourceImpl could resolve getEObject to objects in other
resources, Xtext makes heavy use of that to defer the resolution of
scoped names. In the end I get the sense that it's best to make all
this stuff (the objects corresponding to annotations) look like it's
logically contained in a single resource (the XSD's resource).

I think that's exactly what I was planning to do.
Maybe some rough pseudo code will demonstrate it more clearly.
    class MyXsdResource extends XSDResourceImpl {
        @Override
        void doLoad(...) {
            super.doLoad(...);
            for (annotation in each XSDAnnotation object) {
                appinfoURI = uri???;  // This is the URI I'm talking about
                XMLResource appinfoResource = getResourceSet().createResource(appinfoURI);
                appinfoResource.load(annotation.getDomNode());
                appinfoObject = appinfoResource.getContents().get(0);
                getContents().add(appinfoObject);
            }
        }

        @Override
        EObject getEObject(String uriFragment) {
            Element element = resolveUriFragmentAgainstDOM(uriFragment);
            EObject object = getSchema().getCorrespondingComponent(element);
            if (object instanceof XSDAnnotation) {
                object = resolveAppinfoObjectAgainstContents(element, uriFragment);
            }
        }
    }

I.e. I still need to create XMLResource's internally to de-serialize the appinfo fragments even if the results are added to MyXsdResource contents. And those XMLResources need to be (dummy) members of the ResourceSet in order for the ResourceSet's URIConverter to be called to resolve the base part of any references inside the appinfo fragments(?) Or are you saying they shouldn't be?

[Updated on: Fri, 15 March 2013 10:58]

Report message to a moderator

Re: How to manage mixed XSD/XML resource? [message #1019335 is a reply to message #1019274] Fri, 15 March 2013 13:16 Go to previous message
Ed Merks is currently offline Ed Merks
Messages: 26138
Registered: July 2009
Senior Member
Christer,

Comments below.

On 15/03/2013 11:56 AM, Christer Palm wrote:
> Thanks again Ed for your response!
>
> Ed Merks wrote on Fri, 15 March 2013 02:14
>> The reference will be of the form <URI>#<fragment> and your resource
>> implementation can control what the fragment looks like...
>
> OK, that will be perfectly fine.
> Quote:
>> Similar might not be sufficient. Certainly your
>> ResourceImpl.getEObject must know how to interpret the fragment
>> portion of such a URI.
>>
>> It's designed to be responsible for mapping the <URI> from logic to
>> physical locations and for providing the associated streams. The
>> resource implementations are responsible for producing and consuming
>> the fragment portion.
>
> OK I see, so the URIConverter won't be involved in resolving the
> fragment part. I need to look further into Resource#getEObject then,
> but it it sounds straightforward.
>
> Quote:
>> I still get the sense it would be better to keep all the things that
>> originate from one physical XML (XSD) in a single resource
>> implementation. A fragment URI syntax that's recognizably different
>> from the one used to refer only to the XSD portions should allow for
>> that.
>>
>> You can't expect the fragment to help identity the resource itself.
>> Of course the XSDResourceImpl could resolve getEObject to objects in
>> other resources, Xtext makes heavy use of that to defer the
>> resolution of scoped names. In the end I get the sense that it's
>> best to make all this stuff (the objects corresponding to
>> annotations) look like it's logically contained in a single resource
>> (the XSD's resource).
>
> I think that's exactly what I was planning to do.
> Maybe some rough pseudo code will demonstrate it more clearly.
>
> class MyXsdResource extends XSDResourceImpl {
> @Override
> void doLoad(...) {
> super.doLoad(...);
> for (annotation in each XSDAnnotation object) {
> appinfoURI = uri???; // This is the URI I'm talking about
> XMLResource appinfoResource =
> getResourceSet().createResource(appinfoURI);
> appinfoResource.load(annotation.getDomNode());
> appinfoObject = appinfoResource.getContents().get(0);
> getContents().add(appinfoObject);
Once you add him here, he'll be removed from the other resource you
created. Also keep in mind that proxies URIs will be resolved
(URI.resolve) relative to the URI of the resource into which they're
loaded, so you should make sure the appInfo resource's URI is the same
as the XSD resource's URI.
> }
> }
>
> @Override
> EObject getEObject(String uriFragment) {
> Element element = resolveUriFragmentAgainstDOM(uriFragment);
> EObject object =
> getSchema().getCorrespondingComponent(element);
> if (object instanceof XSDAnnotation) {
> object = resolveAppinfoObjectAgainstContents(element,
> uriFragment);
> }
> }
> }
> I.e. I still need to create XMLResource's internally to de-serialize
> the appinfo fragments even if the results are added to MyXsdResource
> contents. And those XMLResources need to be members of the ResourceSet
> in order for the ResourceSet's URIConverter to be called to resolve
> the base part of any references inside the appinfo fragments(?) Or are
> you saying they shouldn't be?
I think you should move (like you're showing above) the results into the
XSD's resource, so the other resources you create are temporary (and
don't need to be in the resource set).
Previous Topic:[CDO] Derby - Table/View 'CDO_PROPERTIES' does not exist
Next Topic:[CDO] Text Resources are Awesome
Goto Forum:
  


Current Time: Fri Oct 24 07:24:36 GMT 2014

Powered by FUDForum. Page generated in 0.02073 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software