XML Binding to EMF [message #1751144] |
Wed, 04 January 2017 22:30 |
|
I am trying to create an .ecore file based on maven pom.xsd in order to generate maven pom.xml using M2M tools (QVTo). The issue I currently encounter is around properties. Basically, pom allows to specify user defined properties as:
....
<properties>
<name1.version>2.3.7</name1.version>
<name2.version>2.3.7</name2.version>
.....
</properties>
....
Obviously, the name of property will not be defined in XSD as POM allows you to define any property with random name at design time.
XSD Fragment for this:
<xs:element minOccurs="0" name="properties">
<xs:complexType>
<xs:sequence>
<xs:any minOccurs="0" maxOccurs="unbounded" processContents="skip"/>
</xs:sequence>
</xs:complexType>
</xs:element>
And corresponding .ecore generated based on this pom.xsd will create an EClass "PropertiesType" with an EAttribute "any" as EFeatureMapEntry / ExtendedMetaData: kind="elementWildcard", wildcards="##any", name=":0", processing="skip".
To add a new property, I have defined an operation named addInlineProperty(String name, String value) with following implementation:
-- code starts --
public void addInlineProperty(String name, String value) {
final ExtendedMetaData extendedMetaData =
new BasicExtendedMetaData( this.eResource().getResourceSet().getPackageRegistry() );
EStructuralFeature feature = extendedMetaData.demandFeature(mpom4Package.eNS_URI, name, true);
EClass propertyClass = feature. getEContainingClass();
EObject propertyObject = EcoreUtil.create(propertyClass);
FeatureMapUtil.addText(((XMLTypeDocumentRoot)propertyObject).getMixed(),value);
getAny().add(feature, propertyObject);
}
This will all the new property with the name of my choice but the property element gets an @xsi:type attribute as follows:
<?xml version="1.0" encoding="UTF-8"?>
<mpom4:project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mpom4="http://maven.apache.org/myPOM/4.0.0" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<mpom4:properties>
<mpom4:xyz xsi:type="mpom4">122</mpom4:xyz>
</mpom4:properties>
</mpom4:project>
@xsi:type value is the same as the NS_PREFIX of the EPackage I used to demand an EStructuralFeature which is not correct. I would like to either set the proper xsi:type to xsd:string or find a way to ignore at all xsi:type during serialization. I really appreciate any tips. Thanks, Ioan
|
|
|
|
Re: XML Binding to EMF [message #1751161 is a reply to message #1751157] |
Thu, 05 January 2017 07:43 |
|
Ed Merks wrote on Thu, 05 January 2017 02:00Instead of creating an object of the feature's eContainingClass (which is a document root and should never sensibly, in XML terms, be used anywhere except as the single root object of a resource) use XMLTypeFactory.eINSTANCE.createAnyType() to create the what's effectively equivalent to a DOM Node. That AnyType instance has a getMixed method into which you can add the content value and it can be added to the getAny() of the target.
Thanks Ed fro your quick answer. I have tried this as well and I am getting xsi:type="xsd" instead of xsi:type="mpom4". Still not the result I was looking for as I need "xsd:string" or even better a way of skipping xsi:type serialization.
......
public void addInlineProperty(String name, String value) {
final ExtendedMetaData extendedMetaData =
new BasicExtendedMetaData( this.eResource().getResourceSet().getPackageRegistry() );
EStructuralFeature feature = extendedMetaData.demandFeature(mpom4Package.eNS_URI, name, true);
AnyType inlineElement = XMLTypeFactory.eINSTANCE.createAnyType();
FeatureMapUtil.addText(inlineElement.getMixed(),value);
getAny().add(feature, inlineElement);
}
.......
|
|
|
|
Re: XML Binding to EMF [message #1751211 is a reply to message #1751175] |
Thu, 05 January 2017 16:50 |
|
I am using QVTo to create a pom instance, so I guess QVTo uses generated factory. This is just a dummy .qvto file to reproduce the issue:
modeltype mpom4 "strict" uses mpom4('http://maven.apache.org/myPOM/4.0.0');
transformation toMPOM4(out pomOUT:mpom4);
main() {
var docRoot : DocumentRoot := ''.map toPOM();
docRoot.project.properties.addInlineProperty("abc","1.0");
}
mapping String::toPOM() : DocumentRoot {
project := object Model {
properties := object PropertiesType {
};
};
};
I tried to change generated EMF source code:
public class PomResourceImpl extends XMLResourceImpl {
with
public class PomResourceImpl extends GenericXMLResourceImpl {
I still get the same result when I execute the above .qvto transformation. What I noticed, when I used this POM embedded to a different model, xsi:type gets generated with a proper value i.e. "mpom4:DocumentRoot" when I use getContainingClass option. However, my preferred option will be to have no xsi:type at all. From XSD validation perspective, an xsi:type is not necessary when we have in XSD an any type. I guess EMF default behaviour is to save the xsi:type, so when this file is loaded later on, it will help creating proper EMF EObject. I will follow your recommendation to troubleshoot further the default behaviour. Many thanks Ed. All the best and Happy New Year:)
|
|
|
Re: XML Binding to EMF [message #1751217 is a reply to message #1751211] |
Thu, 05 January 2017 18:27 |
Ed Merks Messages: 33136 Registered: July 2009 |
Senior Member |
|
|
Do you see that for your schema-based model there is a generated resource factory? That is where the necessary options are set; changing the base class for your resource implementation isn't likely to help, and if your factory isn't used in the first place, it will of course have no impact. You should ensure that your factory is the one being used to create the resource. And note, that given the file extension is "xml", it's unlikely that you can just globally register your factory against that extension without conflict.
Ed Merks
Professional Support: https://www.macromodeling.com/
|
|
|
Powered by
FUDForum. Page generated in 0.01518 seconds