Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » EMF » XML serialization of non-containment reference
XML serialization of non-containment reference [message #418249] Tue, 08 April 2008 17:57 Go to next message
Eclipse UserFriend
Originally posted by: joerg.von.frantzius.artnology.com

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
</head>
<body bgcolor="#ffffff" text="#000000">
Hi,<br>
<br>
in my model class "WithEObjectCopy", I have a non-containment reference
to some other class "NonContained" (in the same package). I'm creating
an XMLResource, and put a WithEObjectCopy object plus its referenced
NonContained object in it. When I serialize that to XML, I get the
following:<br>
<blockquote><tt>&lt;?xml version="1.0" encoding="UTF-8"?&gt;<br>
&lt;com.artnology.managedobject.test.eobjectcopy:WithEOb jectCopy
xmlns:com.artnology.managedobject.test.eobjectcopy=<a class="moz-txt-link-rfc2396E" href="http:///com/artnology/managedobject/test/eobjectcopy.ecore">"http:///com/artnology/managedobject/test/eobjectcopy.ecore"</a>
someString="bla" nonContained="/1"&gt;<br>
  &lt;contained someDate="2008-04-08T19:00:38.957+0200"/&gt;<br>
&lt;/com.artnology.managedobject.test.eobjectcopy:WithEO bjectCopy&gt; <br>
</tt></blockquote>
Obviously, the NonContained object is not written to the XML, although
it is being referenced. This is using dynamic EMF, i.e. I'm creating
EObjects using "ePackage.getEFactoryInstance().create(eClass)" with the
EPackage loaded from a .ecore file. <br>
<br>
My guess is that I need some kind of document root here, that I add the
two objects to. Unfortunately, I have no generated code to take that
from. Is there a "standard" way of having a (maybe artificial) document
root, with some arbitrary name?<br>
<br>
Maybe I can create a dynamic EClass that has a containment EReference
to WIthEObjectCopy plus a many-valued containment EReference to EObject
for anything referenced by non-containment, and use that as my document
root?<br>
<br>
I don't necessarily want to be able to deserialize the resulting XML.<br>
<br>
Thanks for any hints,<br>
Jörg<br>
</body>
</html>
Re: XML serialization of non-containment reference [message #418250 is a reply to message #418249] Tue, 08 April 2008 18:08 Go to previous messageGo to next message
Ed Merks is currently offline Ed MerksFriend
Messages: 33140
Registered: July 2009
Senior Member
This is a multi-part message in MIME format.
--------------050005090207020403030108
Content-Type: text/plain; charset=ISO-8859-15; format=flowed
Content-Transfer-Encoding: 8bit

J


Ed Merks
Professional Support: https://www.macromodeling.com/
Re: XML serialization of non-containment reference [message #418251 is a reply to message #418250] Tue, 08 April 2008 18:27 Go to previous messageGo to next message
Eclipse UserFriend
Originally posted by: joerg.von.frantzius.artnology.com

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta content="text/html;charset=ISO-8859-15"
http-equiv="Content-Type">
</head>
<body bgcolor="#ffffff" text="#000000">
Hi Ed,<br>
<br>
I already tried to figure out how that article could help me ;)<br>
<br>
For the records, in case anyone else has the same problem, here's what
my code does now:<br>
<blockquote><code><font color="#000000">    OutputStream out = ...;<br>
    EObject objectCopy = ...</font><font color="#000000">;<br>
    List&lt;EObject&gt; referenced = ...; // referenced by
non-containment<br>
</font><br>
<font color="#ffffff">    </font><font color="#000000">ResourceSet resourceSet = </font><font
color="#7f0055"><b>new </b></font><font color="#000000">ResourceSetImpl</font><font
color="#000000">()</font><font color="#000000">;</font><br>
<font color="#ffffff">    </font><font color="#7f0055"><b>final </b></font><font
color="#000000">ExtendedMetaData extendedMetaData = </font ><font
color="#7f0055"><b>new </b></font><font color="#000000">BasicExtendedMetaData</font><font
color="#000000">(</font><font color="#000000">resourceSet.getPackageRegistry</font><font
color="#000000">())</font><font color="#000000">;</font><br>
<font color="#ffffff">    </font><font color="#000000">resourceSet.getLoadOptions</font><font
color="#000000">()</font><font color="#000000">.put</font><font
color="#000000">(</font><font color="#000000">XMLResource.OPTION_EXTENDED_META_DATA, extendedMetaData </font><font
color="#000000">)</font><font color="#000000">;</font><br>
<font color="#ffffff">    </font><font color="#000000"> EStructuralFeature rootNodeFeature = extendedMetaData.dem andFeature </font><font
color="#000000">(</font><font color="#000000">getEPackage</font><font
color="#000000">()</font><font color="#000000">.getNsURI</font><font
color="#000000">()</font><font color="#000000">, </font><font
color="#2a00ff">"rootNode"</font><font color="#000000">, </font><font
color="#7f0055"><b>true</b></font><font color="#000000">)</font><font
color="#000000">;</font><br>
<font color="#ffffff">    </font><font color="#000000">((</font><font
color="#000000">EReference</font><font color="#000000">) </font><font
color="#000000">rootNodeFeature</font><font color="#000000">)</font><font
color="#000000">.setUpperBound</font><font color="#000000">(</font><font
color="#000000">EReference.UNBOUNDED_MULTIPLICITY</font><font
color="#000000">)</font><font color="#000000">;</font><br>
<font color="#ffffff">    </font><font color="#000000"> EClass documentRootClass = rootNodeFeature.getEContaining Class </font><font
color="#000000">()</font><font color="#000000">;</font><br>
<font color="#ffffff">    </font><font color="#000000">EObject documentRoot = EcoreUtil.create </font><font
color="#000000">(</font><font color="#000000">documentRootClass</font><font
color="#000000">)</font><font color="#000000">;</font><br>
<font color="#ffffff">    </font><font color="#000000">List&lt;EObject&gt; contents =  </font><font
color="#7f0055"><b>new </b></font><font color="#000000">ArrayList&lt;EObject&gt;</font><font
color="#000000">()</font><font color="#000000">;</font><br>
<font color="#ffffff">    </font><font color="#000000">documentRoot.eSet</font><font
color="#000000">(</font><font color="#000000">rootNodeFeature, contents</font><font
color="#000000">)</font><font color="#000000">;</font><br>
<br>
<font color="#ffffff">    </font><font color="#3f7f5f"> // the URI in the following is a dummy, make up s omething that tells us something </font><br>
<font color="#ffffff">    </font><font color="#3f7f5f">// should we see it in the debugger </font><br>
<font color="#ffffff">    </font><font color="#000000"> Resource writeXmlResource = XML_RESOURCE_FACTORY.createRe source </font><font
color="#000000">(</font><font color="#000000">URI.createURI</font><font
color="#000000">(</font><font color="#2a00ff">"tostream:"</font><br>
<font color="#ffffff">        </font><font color="#000000">+ getManager</font><font
color="#000000">()</font><font color="#000000">.getModelInterface</font><font
color="#000000">()</font><font color="#000000">.getName</font><font
color="#000000">() </font><font color="#000000">+ </font><font
color="#2a00ff">"/" </font><font color="#000000">+ getIdAsLong</font><font
color="#000000">()))</font><font color="#000000">;</font><br>
<br>
<font color="#ffffff">    </font><font color="#000000">contents.add</font><font
color="#000000">(</font><font color="#000000">objectCopy</font><font
color="#000000">)</font><font color="#000000">;</font><br>
<font color="#ffffff">    </font><font color="#3f7f5f"> // fix all DanglingHREfExceptions (objects that are r eferenced via non-containment associations) </font><br>
<font color="#ffffff">    </font><font color="#7f0055"><b>for </b></font><font
color="#000000">(</font><font color="#000000">EObject eObject :
referenced</font><font color="#000000">) {</font><br>
<font color="#ffffff">      </font><font color="#7f0055"><b>if </b></font><font
color="#000000">(</font><font color="#000000">eObject.eContainer</font><font
color="#000000">() </font><font color="#000000">== </font><font
color="#7f0055"><b>null</b></font><font color="#000000">) {</font><br>
<font color="#ffffff">        </font><font color="#3f7f5f">//writeXmlResource.getContents().add(eObject); </font><br>
<font color="#ffffff">        </font><font color="#000000">contents.add</font><font
color="#000000">(</font><font color="#000000">eObject</font><font
color="#000000">)</font><font color="#000000">;</font><br>
<font color="#ffffff">      </font><font color="#000000">}</font><br>
<font color="#ffffff">    </font><font color="#000000">}</font><br>
<br>
<font color="#ffffff">    </font><font color="#000000">documentRoot.eSet</font><font
color="#000000">(</font><font color="#000000">rootNodeFeature, contents</font><font
color="#000000">)</font><font color="#000000">;</font><br>
<font color="#ffffff">    </font><font color="#000000">writeXmlResource.getContents</font><font
color="#000000">()</font><font color="#000000">.add</font><font
color="#000000">(</font><font color="#000000">documentRoot</font><font
color="#000000">)</font><font color="#000000">;</font><br>
<font color="#ffffff">    </font><font color="#000000">writeXmlResource.save</font><font
color="#000000">(</font><font color="#000000">out, saveOptions</font><font
color="#000000">)</font><font color="#000000">;</font></code></blockquote>
And this is a resulting XML:<br>
<blockquote><tt>&lt;?xml version="1.0" encoding="UTF-8"?&gt;<br>
&lt;eobjectcopy.ecore:DocumentRoot
xmlns:xsi=<a class="moz-txt-link-rfc2396E" href="http://www.w3.org/2001/XMLSchema-instance">"http://www.w3.org/2001/XMLSchema-instance"</a>
xmlns:eobjectcopy.ecore=<a class="moz-txt-link-rfc2396E" href="http:///com/artnology/managedobject/test/eobjectcopy.ecore">"http:///com/artnology/managedobject/test/eobjectcopy.ecore"</a>&gt;<br>
  &lt;rootNode xsi:type="eobjectcopy.ecore:WithEObjectCopy"
someString="bla" nonContained=<a class="moz-txt-link-rfc2396E" href="mailto://@rootNode.1">"//@rootNode.1"</a>&gt;<br>
    &lt;contained someDate="2008-04-08T20:17:49.168+0200"/&gt;<br>
  &lt;/rootNode&gt;<br>
  &lt;rootNode xsi:type="eobjectcopy.ecore:NonContained"/&gt;<br>
&lt;/eobjectcopy.ecore:DocumentRoot&gt;</tt><br>
</blockquote>
That's a good start, thanks!<br>
<br>
Regards,<br>
Jörg<br>
<br>
Ed Merks schrieb:
<blockquote cite="mid:ftgcau$r8n$1@build.eclipse.org" type="cite">
<meta content="text/html;charset=ISO-8859-15"
http-equiv="Content-Type">
Jörg,<br>
<br>
Comments below.<br>
<br>
<br>
Jörg von Frantzius wrote:
<blockquote cite="mid:ftgbn3$f46$1@build.eclipse.org" type="cite">Hi,<br>
<br>
in my model class "WithEObjectCopy", I have a non-containment reference
to some other class "NonContained" (in the same package). I'm creating
an XMLResource, and put a WithEObjectCopy object plus its referenced
NonContained object in it. When I serialize that to XML, I get the
following:<br>
<blockquote><tt>&lt;?xml version="1.0" encoding="UTF-8"?&gt;<br>
&lt;com.artnology.managedobject.test.eobjectcopy:WithEOb jectCopy
xmlns:com.artnology.managedobject.test.eobjectcopy=<a
moz-do-not-send="true" class="moz-txt-link-rfc2396E"
href="http:///com/artnology/managedobject/test/eobjectcopy.ecore">"http:///com/artnology/managedobject/test/eobjectcopy.ecore"</a>
someString="bla" nonContained="/1"&gt;<br>
  &lt;contained someDate="2008-04-08T19:00:38.957+0200"/&gt;<br>
&lt;/com.artnology.managedobject.test.eobjectcopy:WithEO bjectCopy&gt; <br>
</tt></blockquote>
Obviously, the NonContained object is not written to the XML, although
it is being referenced. This is using dynamic EMF, i.e. I'm creating
EObjects using "ePackage.getEFactoryInstance().create(eClass)" with the
EPackage loaded from a .ecore file. <br>
</blockquote>
An XMLResourceImpl won't save multiple roots.   Only an XMIResourceImpl
can do that because it introduces a "fake" XMI root element.<br>
<blockquote cite="mid:ftgbn3$f46$1@build.eclipse.org" type="cite"><br>
My guess is that I need some kind of document root here, that I add the
two objects to. Unfortunately, I have no generated code to take that
from. Is there a "standard" way of having a (maybe artificial) document
root, with some arbitrary name?<br>
</blockquote>
Yes, you need some type of container that can hold multiple children
and put your objects under it.  Or use XMIResourceImpl.<br>
<blockquote cite="mid:ftgbn3$f46$1@build.eclipse.org" type="cite"><br>
Maybe I can create a dynamic EClass that has a containment EReference
to WIthEObjectCopy plus a many-valued containment EReference to EObject
for anything referenced by non-containment, and use that as my document
root?<br>
</blockquote>
You can definitely demand create metadata for that type of thing.  And
instance of AnyType could be used to contain multiple children.  This
article will be helpful...<br>
<blockquote><a moz-do-not-send="true" target="_out"
href=" http://www.theserverside.com/tt/articles/article.tss?l=Bindi ngXMLJava">Binding
XML to Java</a></blockquote>
<blockquote cite="mid:ftgbn3$f46$1@build.eclipse.org" type="cite"><br>
I don't necessarily want to be able to deserialize the resulting XML.<br>
<br>
Thanks for any hints,<br>
Jörg<br>
</blockquote>
<br>
</blockquote>
<br>
</body>
</html>
Re: XML serialization of non-containment reference [message #418253 is a reply to message #418251] Tue, 08 April 2008 20:00 Go to previous messageGo to next message
Ed Merks is currently offline Ed MerksFriend
Messages: 33140
Registered: July 2009
Senior Member
Jörg,

Comments below.

Jörg von Frantzius wrote:
> Hi Ed,
>
> I already tried to figure out how that article could help me ;)
>
> For the records, in case anyone else has the same problem, here's what
> my code does now:
>
> | OutputStream out = ...;
> EObject objectCopy = ...;
> List<EObject> referenced = ...; // referenced by non-containment
>
> ResourceSet resourceSet = *new *ResourceSetImpl();
> *final *ExtendedMetaData extendedMetaData = *new *BasicExtendedMetaData(resourceSet.getPackageRegistry());
> resourceSet.getLoadOptions().put(XMLResource.OPTION_EXTENDED _META_DATA, extendedMetaData);
> EStructuralFeature rootNodeFeature = extendedMetaData.demandFeature(getEPackage().getNsURI(), "rootNode", *true*);
> ((EReference) rootNodeFeature).setUpperBound(EReference.UNBOUNDED_MULTIPLI CITY);
> EClass documentRootClass = rootNodeFeature.getEContainingClass();
> EObject documentRoot = EcoreUtil.create(documentRootClass);
> List<EObject> contents = *new *ArrayList<EObject>();
> documentRoot.eSet(rootNodeFeature, contents);
> |
>
I'm surprised this works. I'd have figured you'd create a root feature,
put an AnyType instance under it, and then under that add two contained
children.
>
> |
> // the URI in the following is a dummy, make up something that tells us something
> // should we see it in the debugger
> Resource writeXmlResource = XML_RESOURCE_FACTORY.createResource(URI.createURI("tostream: "
> + getManager().getModelInterface().getName() + "/" + getIdAsLong()));
>
> contents.add(objectCopy);
> // fix all DanglingHREfExceptions (objects that are referenced via non-containment associations)
> *for *(EObject eObject : referenced) {
> *if *(eObject.eContainer() == *null*) {
> //writeXmlResource.getContents().add(eObject);
> contents.add(eObject);
> }
> }
>
> documentRoot.eSet(rootNodeFeature, contents);
> writeXmlResource.getContents().add(documentRoot);
> writeXmlResource.save(out, saveOptions);|
>
> And this is a resulting XML:
>
> <?xml version="1.0" encoding="UTF-8"?>
> <eobjectcopy.ecore:DocumentRoot
> xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
>
This tells me you're likely not using the extended meta data option to
save the result, and if you did you'd get invalid XML...
>
> xmlns:eobjectcopy.ecore="http:///com/artnology/managedobject/test/eobjectcopy.ecore">
> <rootNode xsi:type="eobjectcopy.ecore:WithEObjectCopy"
> someString="bla" nonContained="//@rootNode.1">
> <contained someDate="2008-04-08T20:17:49.168+0200"/>
> </rootNode>
> <rootNode xsi:type="eobjectcopy.ecore:NonContained"/>
> </eobjectcopy.ecore:DocumentRoot>
>
> That's a good start, thanks!
I feel like I'm bursting the balloon. I think it would be better to
create an any type root object, like above but eSet the anyType instance
to the root feature, and define a child element feature for which you'd
use anyType.getAny().add(<childFeature>, childObject)...
>
> Regards,
> Jörg
>
> Ed Merks schrieb:
>> Jörg,
>>
>> Comments below.
>>
>>
>> Jörg von Frantzius wrote:
>>> Hi,
>>>
>>> in my model class "WithEObjectCopy", I have a non-containment
>>> reference to some other class "NonContained" (in the same package).
>>> I'm creating an XMLResource, and put a WithEObjectCopy object plus
>>> its referenced NonContained object in it. When I serialize that to
>>> XML, I get the following:
>>>
>>> <?xml version="1.0" encoding="UTF-8"?>
>>> < com.artnology.managedobject.test.eobjectcopy:WithEObjectCopy
>>> xmlns:com.artnology.managedobject.test.eobjectcopy="http:///com/artnology/managedobject/test/eobjectcopy.ecore"
>>> someString="bla" nonContained="/1">
>>> <contained someDate="2008-04-08T19:00:38.957+0200"/>
>>> < /com.artnology.managedobject.test.eobjectcopy:WithEObjectCop y >
>>>
>>> Obviously, the NonContained object is not written to the XML,
>>> although it is being referenced. This is using dynamic EMF, i.e. I'm
>>> creating EObjects using
>>> "ePackage.getEFactoryInstance().create(eClass)" with the EPackage
>>> loaded from a .ecore file.
>> An XMLResourceImpl won't save multiple roots. Only an
>> XMIResourceImpl can do that because it introduces a "fake" XMI root
>> element.
>>>
>>> My guess is that I need some kind of document root here, that I add
>>> the two objects to. Unfortunately, I have no generated code to take
>>> that from. Is there a "standard" way of having a (maybe artificial)
>>> document root, with some arbitrary name?
>> Yes, you need some type of container that can hold multiple children
>> and put your objects under it. Or use XMIResourceImpl.
>>>
>>> Maybe I can create a dynamic EClass that has a containment
>>> EReference to WIthEObjectCopy plus a many-valued containment
>>> EReference to EObject for anything referenced by non-containment,
>>> and use that as my document root?
>> You can definitely demand create metadata for that type of thing.
>> And instance of AnyType could be used to contain multiple children.
>> This article will be helpful...
>>
>> Binding XML to Java
>> < http://www.theserverside.com/tt/articles/article.tss?l=Bindi ngXMLJava>
>>
>>>
>>> I don't necessarily want to be able to deserialize the resulting XML.
>>>
>>> Thanks for any hints,
>>> Jörg
>>
>


Ed Merks
Professional Support: https://www.macromodeling.com/
Re: XML serialization of non-containment reference [message #418260 is a reply to message #418253] Wed, 09 April 2008 09:01 Go to previous messageGo to next message
Eclipse UserFriend
Originally posted by: joerg.von.frantzius.artnology.com

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta content="text/html;charset=ISO-8859-15"
http-equiv="Content-Type">
<title></title>
</head>
<body bgcolor="#ffffff" text="#000000">
Hello Ed,<br>
<br>
OK I tried using an AnyType and adding things to that. When I add them
to the AnyType individually, I get ugly references like
"<tt>//@rootNode/@mixed.2</tt>". I'm not sure yet whether it'll be easy
to use
that as XPath expressions in XSLT. What I would like to do here is
adding all referenced objects of the same class into the same
many-valued feature, with the feature named after the EClass'
uncapName. <br>
<br>
However, when I try to do the following:<br>
<blockquote><tt>        for (EClass referencedClass :
referencedObjectsByClass.keySet()) {<br>
            EReference referencedContentFeature = (EReference)
extendedMetaData.demandFeature(getEPackage().getNsURI(),<br >
                   
firstCharacterToLowerCase(referencedClass.getName()), true, true);<br>
            <b> referencedContentFeature.setUpperBound(EReference.UNBOUNDED_ MULTIPLICITY) </b>;<br>
            final List&lt;EObject&gt; list =
referencedObjectsByClass.get(referencedClass);<br>
            anyType.getAny().add(referencedContentFeature, list);<br>
        }<br>
</tt></blockquote>
I get an exception<br>
<blockquote><tt>java.lang.ClassCastException: The feature
'nonContained's type 'EObject' does not permit a value of type
'java.util.ArrayList'<br>
    at
org.eclipse.emf.ecore.impl.EStructuralFeatureImpl$BasicFeatu reMapEntry.validate(EStructuralFeatureImpl.java:2891) <br>
    at
org.eclipse.emf.ecore.util.FeatureMapUtil.createEntry(Featur eMapUtil.java:180) <br>
    at
org.eclipse.emf.ecore.util.BasicFeatureMap.createEntry(Basic FeatureMap.java:101) <br>
    at
org.eclipse.emf.ecore.util.BasicFeatureMap.add(BasicFeatureM ap.java:1155) <br>
    at
org.eclipse.emf.ecore.util.FeatureMapUtil$FeatureFeatureMap. add(FeatureMapUtil.java:958) </tt><br>
</blockquote>
Is it not possible to have a many-valued feature on a FeatureMap? In my
previous approach of adding everything directly on the DocumentRoot, I
was able to call<br>
<blockquote><tt>documentRoot.eSet(referencedContentFeature, list);</tt><br>
</blockquote>
without problems. <br>
<br>
<br>
Ed Merks schrieb:
<blockquote cite="mid:ftgit3$k8j$1@build.eclipse.org" type="cite">Jörg,
<br>
<br>
Comments below.
<br>
<br>
Jörg von Frantzius wrote:
<br>
<blockquote type="cite">Hi Ed,
<br>
<br>
I already tried to figure out how that article could help me ;)
<br>
<br>
For the records, in case anyone else has the same problem, here's what
my code does now:
<br>
<br>
    |    OutputStream out = ...;
<br>
        EObject objectCopy = ...;
<br>
        List&lt;EObject&gt; referenced = ...; // referenced by
non-containment
<br>
<br>
        ResourceSet resourceSet = *new *ResourceSetImpl();
<br>
        *final *ExtendedMetaData extendedMetaData = *new
*BasicExtendedMetaData(resourceSet.getPackageRegistry());
<br>
       
resourceSet.getLoadOptions().put(XMLResource.OPTION_EXTENDED _META_DATA,
extendedMetaData);
<br>
        EStructuralFeature rootNodeFeature =
extendedMetaData.demandFeature(getEPackage().getNsURI(), "rootNode",
*true*);
<br>
        ((EReference)
rootNodeFeature).setUpperBound(EReference.UNBOUNDED_MULTIPLI CITY);
<br>
        EClass documentRootClass =
rootNodeFeature.getEContainingClass();
<br>
        EObject documentRoot = EcoreUtil.create(documentRootClass);
<br>
        List&lt;EObject&gt; contents = *new
*ArrayList&lt;EObject&gt;();
<br>
        documentRoot.eSet(rootNodeFeature, contents);
<br>
    |
<br>
<br>
</blockquote>
I'm surprised this works.  I'd have figured you'd create a root
feature, put an AnyType instance under it, and then under that add two
contained children.
<br>
<blockquote type="cite"><br>
    |
<br>
        // the URI in the following is a dummy, make up something that
tells us something
<br>
        // should we see it in the debugger
<br>
        Resource writeXmlResource =
XML_RESOURCE_FACTORY.createResource(URI.createURI("tostream: "
<br>
            + getManager().getModelInterface().getName() + "/" +
getIdAsLong()));
<br>
<br>
        contents.add(objectCopy);
<br>
        // fix all DanglingHREfExceptions (objects that are referenced
via non-containment associations)
<br>
        *for *(EObject eObject : referenced) {
<br>
          *if *(eObject.eContainer() == *null*) {
<br>
            //writeXmlResource.getContents().add(eObject);
<br>
            contents.add(eObject);
<br>
          }
<br>
        }
<br>
<br>
        documentRoot.eSet(rootNodeFeature, contents);
<br>
        writeXmlResource.getContents().add(documentRoot);
<br>
        writeXmlResource.save(out, saveOptions);|
<br>
<br>
And this is a resulting XML:
<br>
<br>
    &lt;?xml version="1.0" encoding="UTF-8"?&gt;
<br>
    &lt;eobjectcopy.ecore:DocumentRoot
<br>
    xmlns:xsi=<a class="moz-txt-link-rfc2396E" href="http://www.w3.org/2001/XMLSchema-instance">"http://www.w3.org/2001/XMLSchema-instance"</a>
<br>
<br>
</blockquote>
This tells me you're likely not using the extended meta data option to
save the result, and if you did you'd get invalid XML...
<br>
<blockquote type="cite"><br>
   
xmlns:eobjectcopy.ecore=<a class="moz-txt-link-rfc2396E" href="http:///com/artnology/managedobject/test/eobjectcopy.ecore">"http:///com/artnology/managedobject/test/eobjectcopy.ecore"</a>&gt;
<br>
      &lt;rootNode xsi:type="eobjectcopy.ecore:WithEObjectCopy"
<br>
    someString="bla" nonContained=<a class="moz-txt-link-rfc2396E" href="mailto://@rootNode.1">"//@rootNode.1"</a>&gt;
<br>
        &lt;contained someDate="2008-04-08T20:17:49.168+0200"/&gt;
<br>
      &lt;/rootNode&gt;
<br>
      &lt;rootNode xsi:type="eobjectcopy.ecore:NonContained"/&gt;
<br>
    &lt;/eobjectcopy.ecore:DocumentRoot&gt;
<br>
<br>
That's a good start, thanks!
<br>
</blockquote>
I feel like I'm bursting the balloon.  I think it would be better to
create an any type root object, like above but eSet the anyType
instance to the root feature, and define a child element feature for
which you'd use anyType.getAny().add(&lt;childFeature&gt;,
childObject)...
<br>
<blockquote type="cite"><br>
Regards,
<br>
Jörg
<br>
<br>
Ed Merks schrieb:
<br>
<blockquote type="cite">Jörg,
<br>
<br>
Comments below.
<br>
<br>
<br>
Jörg von Frantzius wrote:
<br>
<blockquote type="cite">Hi,
<br>
<br>
in my model class "WithEObjectCopy", I have a non-containment reference
to some other class "NonContained" (in the same package). I'm creating
an XMLResource, and put a WithEObjectCopy object plus its referenced
NonContained object in it. When I serialize that to XML, I get the
following:
<br>
<br>
    &lt;?xml version="1.0" encoding="UTF-8"?&gt;
<br>
    &lt;com.artnology.managedobject.test.eobjectcopy:WithEOb jectCopy
<br>
   
xmlns:com.artnology.managedobject.test.eobjectcopy=<a class="moz-txt-link-rfc2396E" href="http:///com/artnology/managedobject/test/eobjectcopy.ecore">"http:///com/artnology/managedobject/test/eobjectcopy.ecore"</a>
<br>
    someString="bla" nonContained="/1"&gt;
<br>
      &lt;contained someDate="2008-04-08T19:00:38.957+0200"/&gt;
<br>
   
&lt;/com.artnology.managedobject.test.eobjectcopy:WithEO bjectCopy&gt;
<br>
<br>
Obviously, the NonContained object is not written to the XML, although
it is being referenced. This is using dynamic EMF, i.e. I'm creating
EObjects using "ePackage.getEFactoryInstance().create(eClass)" with the
EPackage loaded from a .ecore file.
<br>
</blockquote>
An XMLResourceImpl won't save multiple roots.   Only an XMIResourceImpl
can do that because it introduces a "fake" XMI root element.
<br>
<blockquote type="cite"><br>
My guess is that I need some kind of document root here, that I add the
two objects to. Unfortunately, I have no generated code to take that
from. Is there a "standard" way of having a (maybe artificial) document
root, with some arbitrary name?
<br>
</blockquote>
Yes, you need some type of container that can hold multiple children
and put your objects under it.  Or use XMIResourceImpl.
<br>
<blockquote type="cite"><br>
Maybe I can create a dynamic EClass that has a containment EReference
to WIthEObjectCopy plus a many-valued containment EReference to EObject
for anything referenced by non-containment, and use that as my document
root?
<br>
</blockquote>
You can definitely demand create metadata for that type of thing.  And
instance of AnyType could be used to contain multiple children.  This
article will be helpful...
<br>
<br>
    Binding XML to Java
<br>
   
<a class="moz-txt-link-rfc2396E" href=" http://www.theserverside.com/tt/articles/article.tss?l=Bindi ngXMLJava">&lt; http://www.theserverside.com/tt/articles/article.tss?l=Bindi ngXMLJava&gt;</a>
<br>
<br>
<blockquote type="cite"><br>
I don't necessarily want to be able to deserialize the resulting XML.
<br>
<br>
Thanks for any hints,
<br>
Jörg
<br>
</blockquote>
<br>
</blockquote>
<br>
</blockquote>
</blockquote>
<br>
</body>
</html>
Re: XML serialization of non-containment reference [message #418266 is a reply to message #418260] Wed, 09 April 2008 11:22 Go to previous messageGo to next message
Ed Merks is currently offline Ed MerksFriend
Messages: 33140
Registered: July 2009
Senior Member
This is a multi-part message in MIME format.
--------------050408090001020203080803
Content-Type: text/plain; charset=ISO-8859-15; format=flowed
Content-Transfer-Encoding: 8bit

J


Ed Merks
Professional Support: https://www.macromodeling.com/
Re: XML serialization of non-containment reference [message #418269 is a reply to message #418266] Wed, 09 April 2008 11:41 Go to previous messageGo to next message
Eclipse UserFriend
Originally posted by: joerg.von.frantzius.artnology.com

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta content="text/html;charset=ISO-8859-15"
http-equiv="Content-Type">
</head>
<body bgcolor="#ffffff" text="#000000">
Ed Merks schrieb:
<blockquote cite="mid:fti8t5$q4n$1@build.eclipse.org" type="cite">
<meta content="text/html;charset=ISO-8859-15"
http-equiv="Content-Type">
Jörg,<br>
<br>
Comments below.<br>
<br>
Jörg von Frantzius wrote:
<blockquote cite="mid:fti0l6$i7a$1@build.eclipse.org" type="cite">
<meta content="text/html;charset=ISO-8859-15"
http-equiv="Content-Type">
<title></title>
Hello Ed,<br>
<br>
OK I tried using an AnyType and adding things to that. When I add them
to the AnyType individually, I get ugly references like
"<tt>//@rootNode/@mixed.2</tt>".</blockquote>
Hehehe.  Beauty is in the eye of the beholder.  If your objects has
EAttribute's for which isID is true, that value would be used instead...<br>
</blockquote>
Would that attribute have to be unique among everything within the same
resource, or does it suffice to have it unique among all objects of the
same class? The former, I'm afraid...<br>
<blockquote cite="mid:fti8t5$q4n$1@build.eclipse.org" type="cite">
<blockquote cite="mid:fti0l6$i7a$1@build.eclipse.org" type="cite">
I'm
not sure yet whether it'll be easy
to use
that as XPath expressions in XSLT. What I would like to do here is
adding all referenced objects of the same class into the same
many-valued feature, with the feature named after the EClass'
uncapName. <br>
</blockquote>
Yes, it would be quite cool to be able to support xpaths in general,
but such things often need to refer to namespaces and hence need to use
QNames where the prefix for the namespace is information known only to
the serializer...<br>
</blockquote>
Do you per chance know of a good approach to turn these references into
XPath expressions, like when trying to make use of the references in
XSLT?<br>
<blockquote cite="mid:fti8t5$q4n$1@build.eclipse.org" type="cite">
<blockquote cite="mid:fti0l6$i7a$1@build.eclipse.org" type="cite"><br>
However, when I try to do the following:<br>
<blockquote><tt>        for (EClass referencedClass :
referencedObjectsByClass.keySet()) {<br>
            EReference referencedContentFeature = (EReference)
extendedMetaData.demandFeature(getEPackage().getNsURI(),<br >
                   
firstCharacterToLowerCase(referencedClass.getName()), true, true);<br>
            <b> referencedContentFeature.setUpperBound(EReference.UNBOUNDED_ MULTIPLICITY) </b>;<br>
            final List&lt;EObject&gt; list =
referencedObjectsByClass.get(referencedClass);<br>
            anyType.getAny().add(referencedContentFeature, list);<br>
</tt></blockquote>
</blockquote>
<tt><b>//
referencedContentFeature.setUpperBound(EReference.UNBOUNDED_ MULTIPLICITY) </b>;<br>
// final List&lt;EObject&gt; list =
referencedObjectsByClass.get(referencedClass);<br>
// anyType.getAny().add(referencedContentFeature, list);<br>
<br>
</tt><tt>for (EObject eObject : </tt><tt>referencedObjectsByClass.get(referencedClass))<br >
{<br>
</tt><tt>  anyType.getAny().add(referencedContentFeature, eObject);<br>
}<br>
</tt>
<blockquote cite="mid:fti0l6$i7a$1@build.eclipse.org" type="cite">
<blockquote><tt>        }<br>
</tt></blockquote>
I get an exception<br>
<blockquote><tt>java.lang.ClassCastException: The feature
'nonContained's type 'EObject' does not permit a value of type
'java.util.ArrayList'<br>
    at
org.eclipse.emf.ecore.impl.EStructuralFeatureImpl$BasicFeatu reMapEntry.validate(EStructuralFeatureImpl.java:2891) <br>
    at
org.eclipse.emf.ecore.util.FeatureMapUtil.createEntry(Featur eMapUtil.java:180) <br>
    at
org.eclipse.emf.ecore.util.BasicFeatureMap.createEntry(Basic FeatureMap.java:101) <br>
    at
org.eclipse.emf.ecore.util.BasicFeatureMap.add(BasicFeatureM ap.java:1155) <br>
    at
org.eclipse.emf.ecore.util.FeatureMapUtil$FeatureFeatureMap. add(FeatureMapUtil.java:958) </tt><br>
</blockquote>
Is it not possible to have a many-valued feature on a FeatureMap? In my
previous approach of adding everything directly on the DocumentRoot, I
was able to call<br>
<blockquote><tt>documentRoot.eSet(referencedContentFeature, list);</tt><br>
</blockquote>
without problems. <br>
</blockquote>
No.  Even for a multi-valued feature, the feature map entry is still a
feature single value pair.  I.e., the value of the feature map entry
must <b>always </b>be a value of the features type and the
multiplicity affects only whether it's valid to have multiple such
entries in the feature map.<br>
<blockquote cite="mid:fti0l6$i7a$1@build.eclipse.org" type="cite"><br>
<br>
Ed Merks schrieb:
<blockquote cite="mid:ftgit3$k8j$1@build.eclipse.org" type="cite">Jörg,
<br>
<br>
Comments below. <br>
<br>
Jörg von Frantzius wrote: <br>
<blockquote type="cite">Hi Ed, <br>
<br>
I already tried to figure out how that article could help me ;) <br>
<br>
For the records, in case anyone else has the same problem, here's what
my code does now: <br>
<br>
    |    OutputStream out = ...; <br>
        EObject objectCopy = ...; <br>
        List&lt;EObject&gt; referenced = ...; // referenced by
non-containment <br>
<br>
        ResourceSet resourceSet = *new *ResourceSetImpl(); <br>
        *final *ExtendedMetaData extendedMetaData = *new
*BasicExtendedMetaData(resourceSet.getPackageRegistry()); <br>
       
resourceSet.getLoadOptions().put(XMLResource.OPTION_EXTENDED _META_DATA,
extendedMetaData); <br>
        EStructuralFeature rootNodeFeature =
extendedMetaData.demandFeature(getEPackage().getNsURI(), "rootNode",
*true*); <br>
        ((EReference)
rootNodeFeature).setUpperBound(EReference.UNBOUNDED_MULTIPLI CITY); <br>
        EClass documentRootClass =
rootNodeFeature.getEContainingClass(); <br>
        EObject documentRoot = EcoreUtil.create(documentRootClass); <br>
        List&lt;EObject&gt; contents = *new
*ArrayList&lt;EObject&gt;(); <br>
        documentRoot.eSet(rootNodeFeature, contents); <br>
    | <br>
<br>
</blockquote>
I'm surprised this works.  I'd have figured you'd create a root
feature, put an AnyType instance under it, and then under that add two
contained children. <br>
<blockquote type="cite"><br>
    | <br>
        // the URI in the following is a dummy, make up something that
tells us something <br>
        // should we see it in the debugger <br>
        Resource writeXmlResource =
XML_RESOURCE_FACTORY.createResource(URI.createURI("tostream: " <br>
            + getManager().getModelInterface().getName() + "/" +
getIdAsLong())); <br>
<br>
        contents.add(objectCopy); <br>
        // fix all DanglingHREfExceptions (objects that are referenced
via non-containment associations) <br>
        *for *(EObject eObject : referenced) { <br>
          *if *(eObject.eContainer() == *null*) { <br>
            //writeXmlResource.getContents().add(eObject); <br>
            contents.add(eObject); <br>
          } <br>
        } <br>
<br>
        documentRoot.eSet(rootNodeFeature, contents); <br>
        writeXmlResource.getContents().add(documentRoot); <br>
        writeXmlResource.save(out, saveOptions);| <br>
<br>
And this is a resulting XML: <br>
<br>
    &lt;?xml version="1.0" encoding="UTF-8"?&gt; <br>
    &lt;eobjectcopy.ecore:DocumentRoot <br>
    xmlns:xsi=<a moz-do-not-send="true" class="moz-txt-link-rfc2396E"
href="http://www.w3.org/2001/XMLSchema-instance">"http://www.w3.org/2001/XMLSchema-instance"</a>
<br>
<br>
</blockquote>
This tells me you're likely not using the extended meta data option to
save the result, and if you did you'd get invalid XML... <br>
<blockquote type="cite"><br>
   
xmlns:eobjectcopy.ecore=<a moz-do-not-send="true"
class="moz-txt-link-rfc2396E"
href="http:///com/artnology/managedobject/test/eobjectcopy.ecore">"http:///com/artnology/managedobject/test/eobjectcopy.ecore"</a>&gt;
<br>
      &lt;rootNode xsi:type="eobjectcopy.ecore:WithEObjectCopy" <br>
    someString="bla" nonContained=<a moz-do-not-send="true"
class="moz-txt-link-rfc2396E" href="mailto://@rootNode.1">"//@rootNode.1"</a>&gt;
<br>
        &lt;contained someDate="2008-04-08T20:17:49.168+0200"/&gt; <br>
      &lt;/rootNode&gt; <br>
      &lt;rootNode xsi:type="eobjectcopy.ecore:NonContained"/&gt; <br>
    &lt;/eobjectcopy.ecore:DocumentRoot&gt; <br>
<br>
That's a good start, thanks! <br>
</blockquote>
I feel like I'm bursting the balloon.  I think it would be better to
create an any type root object, like above but eSet the anyType
instance to the root feature, and define a child element feature for
which you'd use anyType.getAny().add(&lt;childFeature&gt;,
childObject)... <br>
<blockquote type="cite"><br>
Regards, <br>
Jörg <br>
<br>
Ed Merks schrieb: <br>
<blockquote type="cite">Jörg, <br>
<br>
Comments below. <br>
<br>
<br>
Jörg von Frantzius wrote: <br>
<blockquote type="cite">Hi, <br>
<br>
in my model class "WithEObjectCopy", I have a non-containment reference
to some other class "NonContained" (in the same package). I'm creating
an XMLResource, and put a WithEObjectCopy object plus its referenced
NonContained object in it. When I serialize that to XML, I get the
following: <br>
<br>
    &lt;?xml version="1.0" encoding="UTF-8"?&gt; <br>
    &lt;com.artnology.managedobject.test.eobjectcopy:WithEOb jectCopy <br>
   
xmlns:com.artnology.managedobject.test.eobjectcopy=<a
moz-do-not-send="true" class="moz-txt-link-rfc2396E"
href="http:///com/artnology/managedobject/test/eobjectcopy.ecore">"http:///com/artnology/managedobject/test/eobjectcopy.ecore"</a>
<br>
    someString="bla" nonContained="/1"&gt; <br>
      &lt;contained someDate="2008-04-08T19:00:38.957+0200"/&gt; <br>
   
&lt;/com.artnology.managedobject.test.eobjectcopy:WithEO bjectCopy&gt; <br>
<br>
Obviously, the NonContained object is not written to the XML, although
it is being referenced. This is using dynamic EMF, i.e. I'm creating
EObjects using "ePackage.getEFactoryInstance().create(eClass)" with the
EPackage loaded from a .ecore file. <br>
</blockquote>
An XMLResourceImpl won't save multiple roots.   Only an XMIResourceImpl
can do that because it introduces a "fake" XMI root element. <br>
<blockquote type="cite"><br>
My guess is that I need some kind of document root here, that I add the
two objects to. Unfortunately, I have no generated code to take that
from. Is there a "standard" way of having a (maybe artificial) document
root, with some arbitrary name? <br>
</blockquote>
Yes, you need some type of container that can hold multiple children
and put your objects under it.  Or use XMIResourceImpl. <br>
<blockquote type="cite"><br>
Maybe I can create a dynamic EClass that has a containment EReference
to WIthEObjectCopy plus a many-valued containment EReference to EObject
for anything referenced by non-containment, and use that as my document
root? <br>
</blockquote>
You can definitely demand create metadata for that type of thing.  And
instance of AnyType could be used to contain multiple children.  This
article will be helpful... <br>
<br>
    Binding XML to Java <br>
    <a moz-do-not-send="true" class="moz-txt-link-rfc2396E"
href=" http://www.theserverside.com/tt/articles/article.tss?l=Bindi ngXMLJava">&lt; http://www.theserverside.com/tt/articles/article.tss?l=Bindi ngXMLJava&gt;</a>
<br>
<br>
<blockquote type="cite"><br>
I don't necessarily want to be able to deserialize the resulting XML. <br>
<br>
Thanks for any hints, <br>
Jörg <br>
</blockquote>
<br>
</blockquote>
<br>
</blockquote>
</blockquote>
<br>
</blockquote>
<br>
</blockquote>
<br>
</body>
</html>
Re: XML serialization of non-containment reference [message #418271 is a reply to message #418269] Wed, 09 April 2008 11:56 Go to previous message
Ed Merks is currently offline Ed MerksFriend
Messages: 33140
Registered: July 2009
Senior Member
This is a multi-part message in MIME format.
--------------070808090602070500000000
Content-Type: text/plain; charset=ISO-8859-15; format=flowed
Content-Transfer-Encoding: 8bit

J


Ed Merks
Professional Support: https://www.macromodeling.com/
Previous Topic:How to get modified model objects
Next Topic:How to get path of workbench
Goto Forum:
  


Current Time: Thu Apr 25 04:02:22 GMT 2024

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

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

Back to the top