jaxb binding simpleType with union doesn't create enum - binding

I have the following schema which I would like to create an enum class
<xs:simpleType name="TopicValuesType">
<xs:union memberTypes="xs:string">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:enumeration value="APPLE"/>
<xs:enumeration value="BANANA"/>
<xs:enumeration value="ORANGE"/>
<xs:enumeration value="#"/>
</xs:restriction>
</xs:simpleType>
</xs:union>
</xs:simpleType>
<xs:complexType name="TopicType">
<xs:attribute name="name" type="TopicValuesType" use="required"/>
</xs:complexType>
I've tried to create a binding class but it doesn't work.
<bindings schemaLocation="MySchema.xsd">
<globalBindings typesafeEnumBase="xs:string" typesafeEnumMemberName="generateName" />
</bindings>
I've read this post XJC does not generate enum inside xs:union where it's not possible to create enum.
Is there any other way to create enum out of this schema? Unfortunately I'm unable to edit the schema because it's from a third party.
I'm using maven jaxb2
<groupId>org.jvnet.jaxb2.maven2</groupId>
<artifactId>maven-jaxb2-plugin</artifactId>
<version>0.14.0</version>

Related

How to implement case/switch in xforms

I have got xsd with choice statement
<xs:complexType name="opt_type">
<xs:choice>
<xs:element name="opt_1_1" minOccurs="0">
<xs:simpleType>
<xs:restriction base="xsd:string">
<xs:enumeration value="opt_1_1 value 1"/>
<xs:enumeration value="opt_1_1 value 2"/>
<xs:enumeration value="opt_1_1 value 3"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element name="opt_1_2" minOccurs="0">
<xs:simpleType>
<xs:restriction base="xsd:string">
<xs:enumeration value="opt_1_2 value"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element name="opt_1_3" minOccurs="0">
<xs:simpleType>
<xs:restriction base="xsd:string">
<xs:enumeration value="opt_1_3 value"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
</xs:choice>
</xs:complexType>
...
<xs:element name="opt" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
...
<xs:element name="opt_1" type="myns:opt_type" minOccurs="0"></xs:element>
...
</xs:sequence>
</xs:complexType>
</xs:element>
I need xforms (I'm working with Orbeon), which will give me, depending on users choice, xml with nodes like those:
<myns:opt_1>
<myns:opt_1_1>opt_1_1 value 1</myns:opt_1_1>
</myns:opt_1>
or
<myns:opt_1>
<myns:opt_1_1>opt_1_1 value 2</myns:opt_1_1>
</myns:opt_1>
or
<myns:opt_1>
<myns:opt_1_1>opt_1_1 value 3</myns:opt_1_1>
</myns:opt_1>
or
<myns:opt_1>
<myns:opt_1_2>opt_1_2 value</myns:opt_1_1>
</myns:opt_1>
or
<myns:opt_1>
<myns:opt_1_3>opt_1_3 value</myns:opt_1_1>
</myns:opt_1>
How can I achieve that?
How should xforms be constructed?
In short you want to change the structure of the XML (using different element names). To do this, your tools should be actions using xf:insert and xf:delete, to insert and delete elements. You need to do this "by hand", as the XForms engine will not do this for you automatically based on the schema.

xsd-reverse-enginering throws unknown type

Was playing around with the xsd-reverse-enginering plugin for grails, and got a bit of a problem which I think I know what it is, but not how to resolve it.
Have a huge xsd file containing a relatively advanced schema, and thought I would try to see if I could save my self a lot of time by getting grails to create a gorm object from it. The problem is that the agency that made the xsd file have named a number of XML types based on what the data is. For example, they have an element called MessageType
<xs:element name="MessageCategory" type="MessageType" id="S1.1">
<xs:annotation>
<xs:documentation>The type of message: either an original Submission (NewSubmission), an update on a submission (SubmissionVariation), a complete replacement of one message with another (SubmissionReplacement) or submission that should not have been sent (SubmissionVoid) that should be effectively deleted.</xs:documentation>
</xs:annotation>
</xs:element>
That throws the below error
Unknown simpleType: MessageType
Any ideas on how I can manage this, could I for example define the types or something?
if you want to declare this type you should define the type tags in a proper way (as described here: http://msdn.microsoft.com/en-US/library/8w07bk3h%28v=vs.80%29.aspx)
for instance: a simple type definition (like a number)
<xs:simpleType name="MessageType">
<xs:restriction base="xs:integer">
<xs:minInclusive value="0"/>
<xs:maxInclusive value="100"/>
</xs:restriction>
</xs:simpleType>
a complex type definition (called an element)
<xs:element name="MessageType">
<xs:simpleType ...>
</xs:simpleType>
<xs:simpleType ...>
</xs:simpleType>
</xs:element>

JAXB binding simple types

I'm trying to generate classes from an xsd but I'm getting the following exception when trying to customize a simple type:
com.sun.istack.SAXParseException2: A type safe enum customization is specified to a simple type that cannot be mapped to a type safe enum.
The declaration of the simple type that throws the exception is as follows:
<xs:simpleType name="BroadcastAlertsItem">
<xs:annotation>
<xs:appinfo>
reserved (0)
broadcastAlertsAccepted (1)
broadcastAlertsNotAccepted (2)
</xs:appinfo>
</xs:annotation>
<xs:union>
<xs:simpleType>
<xs:restriction base="xs:unsignedInt">
<xs:minInclusive value="0"/>
<xs:maxInclusive value="2"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:enumeration value="reserved"/>
<xs:enumeration value="broadcastAlertsAccepted"/>
<xs:enumeration value="broadcastAlertsNotAccepted"/>
</xs:restriction>
</xs:simpleType>
</xs:union>
</xs:simpleType>
And this is the binding from the binding customization file:
<jaxb:bindings node="//xs:simpleType[#name='BroadcastAlertsItem']">
<jaxb:typesafeEnumBase name="BroadcastAlertsItem">
<jaxb:typesafeEnumMember name="reserved"/>
<jaxb:typesafeEnumMember name="broadcastAlertsAccepted"/>
<jaxb:typesafeEnumMember name="broadcastAlertsNotAccepted"/>
</jaxb:typesafeEnumBase>
</jaxb:bindings>
As you will suppose, I have tried many more ways to achieve this goal :(
Does anybody know if there is a way to bind that simple type without modifying the xsd file?
Thank you very much.

Binding - JAXB : XJC Doesn't generate Enum class for an attribute

I have a problem with the XJC tool that it doesn't generate an Enum class for the attribute myEnum using this schema.
<xs:element name="myClass">
<xs:complexType>
<xs:attribute name="myEnum" >
<xs:simpleType >
<xs:restriction base="xs:string">
<xs:maxLength value="1"/>
<xs:enumeration value="C"/>
<xs:enumeration value="M"/>
<xs:enumeration value="S"/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
</xs:complexType>
</xs:element>
but it generates it if I use only this
<xs:simpleType >
<xs:restriction base="xs:string">
<xs:maxLength value="1"/>
<xs:enumeration value="C"/>
<xs:enumeration value="M"/>
<xs:enumeration value="S"/>
</xs:restriction>
</xs:simpleType>
here is the external binding file content :
<?xml version="1.0" encoding="UTF-8" ?>
<bindings xmlns="http://java.sun.com/xml/ns/jaxb"
version="2.1" xmlns:xs="http://www.w3.org/2001/XMLSchema"
>
<globalBindings typesafeEnumMemberName="generateName">
</globalBindings>
</bindings>
You could try this: define a small XSD file with just that particular type declared as a global type, e.g.:
<xs:simpleType name="myEnumSimpleType">
<xs:restriction base="xs:string">
<xs:maxLength value="1"/>
<xs:enumeration value="C"/>
<xs:enumeration value="M"/>
<xs:enumeration value="S"/>
</xs:restriction>
</xs:simpleType>
<xs:element name="myClass">
<xs:complexType>
<xs:attribute name="myEnum" type="myEnumSimpleType">
</xs:complexType>
</xs:element>
That will generate a JAXB class (let's call it the 'artificial JAXB class).
Then you can run xjc on the larger XSD and customize the generation to make use of this type for the particular elements.
Alternately, if the JAXB generation from this external XSD is a one-time operation (and then you put the JAXB-generated code in your SVN/Git for instance), then you can rewrite that potion of the code to use your 'artificial' JAXB type instead.
Another you may want to try is to have your binding customization
<globalBindings typesafeEnumMemberName="generateName">
not be a global one, but use expression to try to nail it exactly on this type. It is likely that JAXB will generate a new class for each occurrence, even though they are going to be the same.
Since I find xpath tedious, I would test it out quickly on a local copy of that big XSD, that you modify with the namespace, e.g.
<xs:element name="myClass">
<xs:complexType>
<xs:attribute name="myEnum" >
<xs:simpleType >
<xs:annotation>
<xs:appinfo>
<jaxb:typesafeEnumClass/>
</xs:appinfo>
</xs:annotation> <xs:restriction base="xs:string">
<xs:maxLength value="1"/>
<xs:enumeration value="C"/>
<xs:enumeration value="M"/>
<xs:enumeration value="S"/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
</xs:complexType>
</xs:element>

custom binding to force Inner class creation or getters/setters for xs:element

I have a schema declaration as follow from a third-party provider.
<xs:complexType name="GroupParameterType">
<xs:sequence minOccurs="0" maxOccurs="4">
<xs:element name="name" type="xs:string">
<xs:annotation>
<xs:documentation>The name of the parameter.</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element name="value" type="xs:string">
<xs:annotation>
<xs:documentation>The value of the parameter.</xs:documentation>
</xs:annotation>
</xs:element>
</xs:sequence>
</xs:complexType>
Above is the schema that i CANNOT change. I am trying to write a custom binding for jaxb 2.0 such that I can refer to name as GroupParameterType.Name or GroupParameterType.Value in java code.
Current default binding generates List for me i.e. getNameandValueList, but I want separate getters and setters for name and value respectively.
I tried putting in a custom binding like the following :
<jxb:bindings schemaLocation="GroupParameter.xsd" node="xs:element[#name='name']">
<jxb:globalBindings localScoping="toplevel" generateIsSetMethod="true"/>
</jxb:bindings>
<jxb:bindings schemaLocation="GroupParameter.xsd" node="xs:element[#name='value']">
<jxb:globalBindings localScoping="toplevel" generateIsSetMethod="true"/>
</jxb:bindings>
and it did nothing to change the default class generation. Can anyone give me some pointers as so what else can I try next ? I am looking to have the default List generation ALONG WITH the getters/setters for name and value OR have name and value as Inner Classes. If i remove the maxOccurs=4 option, I can generate getters/setters but since I can't modify the schema, I am trying to get that behavior using external binding file.
Thanks
Shon
You can't get this behaviour unless you modify your schema. You do have a schema model which maps to a heterogeneous element property, and you can't change it with a customization.
You can try the code injection plugin as the last retreat.

Resources