Xml schema interfaces - java

I'm attempting to write an XML schema to define some model classes to be used in jaxb in java.
I would like to be able to define an interface in the xsd but I've no idea how to do this.
For example a lot of my classes will have an attribute called id which is type xs:ID. They will have an attribute called ref which is type xs:IDREF and they will have an attribute called extRef which means that there is a refrence but the element is not specified in the given xml file.
Ideally this would be an interface when converted to java for two reasons.
The classes that implement this are not necessarily connected.
I would like to specify a different inheritance tree for some of these objects.
Example:
<!-- Utility type to be externally referenceable this is too keep all the
externally refrencable attributes in check -->
<xs:complexType name="ExternallyReferenceable" abstract="true">
<xs:attribute name="extRef" type="externalReference" />
<xs:attribute name="id" type="xs:ID" />
<xs:attribute name="ref" type="xs:IDREF" />
</xs:complexType>
<xs:complexType name="ExternalCarPart">
<xs:extension base ="ExternallyReferenceable" />
</xs:complexType>
<xs:complexType name="CarPart">
<xs:extension base ="ExternalCarPart">
<xs:sequence>
<xs:element type="xs:string" name="partName" />
</xs:sequence>
</xs:extension>
</xs:complexType>
<xs:complexType name="CarLamp">
<xs:extension base ="ExternalCarPart">
<xs:sequence>
<xs:element type="xs:string" name="glassPurity" />
</xs:sequence>
</xs:extension>
</xs:complexType>
So in the above example it would be better if exteranllyRefrencable was an interface, and if carpart was an interface.
This would allow CarLamp to inherit from lamp rather than external car part. BicycleLamp could also implement the externallyRefrencable interface and extend lamp also.
Please ask me for clarification if the question isn't clear.

IIRC, JAXB doesn't generate interfaces from XSD.
JAXB also supports generating XSD from Java classes. I'm not sure what it does with interfaces in that regard, but perhaps you need to go at it in the opposite direction - begin with Java and generate XSD, though I'm not sure that will help you.

Related

Most elegant way to make an XSD attribute accept two types (xs:string and xs:long)?

I have received a specification for a SOAP service where the request that I'm sent will contain the following:
<eventContexts>
<eventContext name="eventType" value="Unwind"/>
<eventContext name="referenceId" value="26214"/>
</eventContexts>
I am trying to model this object in the XSD but I'm blocked in the choice of type for the attribute value. As you can see in the above example, it can either be a xs:string (case Unwind) or a xs:long (case 26214).
What type should I choose to make the attribute value accept both xs:string and xs:long?
So far I can think of two things:
1) Should I create two different attributes, e.g. stringValue and longValue:
<xs:complexType name="XmlEventContext">
<xs:attribute name="name" type="xs:string"/>Sh
<xs:attribute name="stringValue" type="xs:string" minOccurs="0"/>
<xs:attribute name="longValue" type="xs:long" minOccurs="0"/>
</xs:complexType>
... and let the client send me the good value in the good attribute? (This looks ugly to me but I'm not a big expert).
2) Should I extend the auto-generated class XmlEventContext with a custom class that takes the value as xs:string and then tries to cast it to xs:long?
public class XmlEventContextComplete extends XmlEventContext {
//code to manage a property referenceId which can either be long or string
}
3) Any other more elegant suggestion?
Thanks in advance!
You want a type that can be either a long or a specific enumerated string.
This should cover that case:
<xs:complexType name="xmlEventContext">
<xs:attribute name="name" type="xs:string" />
<xs:attribute name="value" type="longOrUnwind" />
</xs:complexType>
<xs:simpleType name="longOrUnwind">
<xs:union memberTypes="xs:long unwindConstant" />
</xs:simpleType>
<xs:simpleType name="unwindConstant">
<xs:restriction base="xs:string">
<xs:enumeration value="Unwind" />
</xs:restriction>
</xs:simpleType>

specify type for multiple IDREF attributes in JAXB bindings

Apologies if this is a duplicate question, but I could not find anything for my situation. So here goes:
I have the following in an xsd file:
<xs:complexType name="Allocation">
<xs:annotation>
<xs:documentation>Links its owner to an xs:id.</xs:documentation>
</xs:annotation>
<xs:attribute name="idRef" type="xs:IDREF"/>
</xs:complexType>
<xs:complexType name="XYZ">
<xs:sequence>
<xs:element name="SomeAllocation" type="Allocation"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="ABC">
<xs:sequence>
<xs:element name="SomeAllocation" type="Allocation"/>
</xs:sequence>
</xs:complexType>
I am try to generate fields/getters and setters in java that are of specific types for example XYZ.getSomeAllocation() should return type Object1 and ABC.getSomeAllocation() should return type Object2. The problem I am facing is that xjc is generating one Allocation class and the XYZ and ABC classes with the methods mentioned below returning java.lang.Object types.
Obviously creating to different Allocation types which are then used in the different objects solves the problem but I would like to reuse the object holding the xs:IDREF.
Your help is highly appreciated!
Thanks!

How to maintain package structure when using schemagen and xjc

I am new to JAX B. I created a project with the structure :
src-
entity-
Person
property-
Address
I generate a xsd document using the command
C:\workspace\JAXTest\src>schemagen entity\Person.java property\Address.java
I see schema1.xsd in src folder now but it does not have any package information. So, If I use xjc to generate classes, I get all the classes in the same folder.
C:\workspace\JAXTest\src>xjc schema1.xsd
parsing a schema...
compiling a schema...
generated\Address.java
generated\ObjectFactory.java
generated\Person.java
What can be done so that the xsd can contain the package information so that the generated classes follow the structure of the classes used to create the xsd.
Thanks in advance!
Edit :
There is no particular requirement I am working towards. I am just trying to learn XSD-Class and Class-XSD conversions correctly. Also, I have found that I can use jax customization to specify the global package name but it doesn't work for individual classes. Basically, this does not put my Person in PersonPackage package.
<xs:complexType name="person">
<xs:annotation>
<xs:appinfo>
<jaxb:package name="PersonPackage"/>
</xs:appinfo>
</xs:annotation>
<xs:sequence>
<xs:element name="address" type="address" minOccurs="0">
</xs:element>
<xs:element name="name" type="xs:string" minOccurs="0"/>
</xs:sequence>
</xs:complexType>

How to retrieve values sent from webservice

I have a question about retrieving data values which are sent from a web service. I have a web service which receives data from a client and then does something with it. It worked all perfectly.
But now I wanted to add an extra element to the xsd which handles the message the webservice receives. I've added tests to another complexType which also exists of other elements. The element tests isn't required, but users can add one or more tests in their XML file.
<xs:element name="tests">
<xs:complexType>
<xs:sequence minOccurs="0" maxOccurs="999">
<xs:element name="test">
<xs:complexType>
<xs:sequence minOccurs="1" maxOccurs="unbounded">
<xs:element name="code" type="xs:string" minOccurs="1" maxOccurs="1"/>
<xs:element name="value" type="xs:string" minOccurs="1" maxOccurs="1"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
Whole XSD: http://pastebin.com/TuvYiQzE
I am using JAXB to handle the webservice messages which are send from the client. JAXB automatically generated some code for me:
public Message.Algemeen.TestCode.Tests getTests(){
return tests;
}
And
public List<Message.Algemeen.TestCode.Tests.test> getTest() {
if (test== null) {
test= new ArrayList<Message.Algemeen.TestCode.Tests.test>();
}
return this.test;
}
Now I want to return code and value per element test, the problem is Test and tests are a returned as an object and at the moment I have no idea how to read their value. The method toString() just returns cp.jaxb.classes.Message$Algemeen$Testcode$Tests$test#dcd76a
What am I doing wrong? If you need more code to understand my problem please tell me.
Thanks,
Jef
PS. English isn't my native language, I tried my best to explain my problem.
This line <xs:sequence minOccurs="1" maxOccurs="unbounded"> in the definition of Test means that you can have several code:value pair in test. is this what you want?
I'm no jaxb expert but I was told when designing schemas that it's easier to used name types in this case.
Here you have an list of "unnamed" object (the code:value pair) in a test. And I guess that makes the retrieval difficult.
What happen if you changed to maxOccurs="1"?
what Happen if you defined a new type for your code:value pair and make a list of this element?
could you try to modify it like this:
<xs:element name="tests">
<xs:complexType>
<xs:sequence minOccurs="0" maxOccurs="999">
<xs:element name="test">
<xs:complexType>
<xs:sequence minOccurs="1" maxOccurs="unbounded">
<xs:element name="singleTest">
<xs:complexType>
<xs:sequence minOccurs="1" maxOccurs="1">
<xs:element name="code" type="xs:string" minOccurs="1" maxOccurs="1"/>
<xs:element name="value" type="xs:string" minOccurs="1" maxOccurs="1"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
then you should be able to have something like
List testList = test.getSingleTest()
and iterate to get the code and value for each of them.
What language are you writing your client in? If you're using Java or .Net for example, you should simply be able to invoke your web service method and get a fully formed instance of Test back. As Udo Klimaschewski points out above, this means that you should be able to use something like
getTest().getCode()
To be clear, while it's potentially interesting to look through the XSD, you should not actually need to do this unless your development environment lacks SOAP web service support. The exact mechanism for generating the client side artifacts depends on your language and development environment; as an example, the process for referencing a web service using Netbeans is described here:
http://netbeans.org/kb/docs/websvc/client.html
This should work:
List<Message.Algemeen.TestCode.Tests.test> tests = yourObject.getTest();
for (Message.Algemeen.TestCode.Tests.test test : tests) {
test.getCode(); //Here is test object which contains strings or whatever.
}

Does XSD allow simpleContent and complexContent at the same time?

I want to write an xsd for the xmlrpc spec (and generate java classes out of it using jaxb). The xmlrpc spec allows values like:
<value><int>123</int></value>
<value><boolean>1</boolean></value>
But at the same time it requires:
If no type is indicated, the type is string.
Which means i could receive something like this:
<value>test123</value>
which is equivalent to
<value><string>test123</string></value>
Is there a way to define this in an xsd.
Yes, set a mixed content model on value:
<xs:complexType name="valuetype" mixed="true">
<xs:sequence>
<xs:element name="int" type="xs:int"/>
<xs:element name="boolean" type="xs:boolean"/>
...
</xs:sequence>
</xs:complexType>

Categories

Resources