wood burning stoves 2.0*
The moose likes Web Services and the fly likes JAXB: Two xsd - Create single JAXBContext Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Murach's Java Servlets and JSP this week in the Servlets forum!
JavaRanch » Java Forums » Java » Web Services
Bookmark "JAXB: Two xsd - Create single JAXBContext" Watch "JAXB: Two xsd - Create single JAXBContext" New topic
Author

JAXB: Two xsd - Create single JAXBContext

Ashish Shinde
Ranch Hand

Joined: Dec 08, 2002
Posts: 34
Hi,

I have two xsd Book.xsd and Reviewer.xsd.
The book.xsd has any tag for reviewer.xsd i.e. a book will have a reviewer.
<xsd:any minOccurs="1" maxOccurs="5" namespace="##any" processContents="lax" />

My problem is:
1. How can xjc create classes for both xsd in single package?
Or
2. If two different packages are created for both xsd how to marshal the objects to a file?
Because JAXBContext jc = JAXBContext.newInstance( "<package name>" ); requires package name and not sure which one will it accept.

Thanks,
Ashish
Ivan Krizsan
Ranch Hand

Joined: Oct 04, 2006
Posts: 2198
    
    1
Hi!
I think you can create two JAXBContext objects, using different packages and, for each of the JAXBContext-s you create a marshaller.
When you want to marshal objects to XML, you try the first marshaller. If it produces XML, then you have the XML data you wanted and can continue.
If the marshaller throws an exception or does not produce any data, then try the second marshaller.
If the second marshaller throws an exception or does not produce any data, then you know you have an illegal object tree.
Best wishes!


My free books and tutorials: http://www.slideshare.net/krizsan
Ashish Shinde
Ranch Hand

Joined: Dec 08, 2002
Posts: 34
I tried using both JAXBContexts but each time i get an error --> "toplevel" is not known to this context. Where "toplevel" is the toplevel class for other context.
E.g.: - If Book level context is used to Marshal, the error says "Reviewer" is not known to this context.
or If Reviewer context is used to Marshal, the error says "Book" is not known to this context.

Does it matter if I create the children objects first and then create the parent
before establishing the child-parent relation through setter methods?

Any idea what could be wrong in my approach?
R Srini
Ranch Hand

Joined: Feb 19, 2010
Posts: 215
Hi Ashish.

I am trying to duplicate this. Here is Reviewer.xsd:This is Book.xsd in the same directory with a reference to reviewer in it:From the directory (with these files in it) if you run: This creates three files: ObjectFactory.java, package-info.java and ReviewerType.java. And they are all in a single package, as per your problem# 1. Is this what you were looking for?
Ashish Shinde
Ranch Hand

Joined: Dec 08, 2002
Posts: 34
The reviewer is similar as specified in your sample.
However, my book.xsd has following element which I am using to embed the Reviewer:
<xsd:complexType name="Comments">
<xsd:sequence>
<xsd:any minOccurs="1" maxOccurs="1" namespace="##any"
processContents="lax" />
</xsd:sequence>
</xsd:complexType>

I was not aware that I can use "import" tag to import an xsd.

How do I use "import" in conjunction with the "##any" namespace in book.xsd ?
R Srini
Ranch Hand

Joined: Feb 19, 2010
Posts: 215
How do I use "import" in conjunction with the "##any" namespace in book.xsd ?

Can you explain that a little more, maybe with an example? I didn't understand the question, specifically the "##any" part. Look here for an example of any. Is this preventing you from importing another xsd?
Ashish Shinde
Ranch Hand

Joined: Dec 08, 2002
Posts: 34
The link you have given is pretty much what I am trying to implement.
With 2 xsd (Book and reviewer) and 2 object factories (Book and reviewer) how do i marshal one xml which has book as well as reviewer?

In the example link in your post below,
nowhere in BookType schema it refers the Reviewer xsd.
However the final xml depicted has a Reviewer.

I want to achieve the same.
The BookType xsd has <xsd:any namespace="##any" minOccurs="0"/> with no reference to Reviewer xsd.
How will it know that the namespace="##any" will accmodate the reviewer?
R Srini
Ranch Hand

Joined: Feb 19, 2010
Posts: 215
Hi Ashish. Have you been provided the xsds and asked to use them or are you creating them? Are you in a position to change the Book xsd and add a Reviewer reference to it? Then you will be set. If not, then I don't have an immediate answer, and will have try it out.
Ashish Shinde
Ranch Hand

Joined: Dec 08, 2002
Posts: 34


The xsd's have been provided and not allowed to modify it.
Manan Panchal
Greenhorn

Joined: Nov 17, 2008
Posts: 24
Please, try this...
This may solve your problem.
This xsds may same as yours.
Book.xsd

Reviewer.xsd

And, this is binding file
Binding.xjb

And, run this command.

xjc Reviewer.xsd Book.xsd -b binding.xjb

This will create all classes in same package.
Ashish Shinde
Ranch Hand

Joined: Dec 08, 2002
Posts: 34
Thanks. Tried using this approach. However when the xjc command runs, it gives the following error:

[ERROR] The processing instruction target matching "[xX][mM][lL]" is not allowed
line 1 of file c:\work\src\bindings.xjb


Ran individual xsd files with xjb and they are generating the classes.
Have verified the xsd files and there are no HTML style (<!-- -->) comments
My Reviewer xsd filename is "reviewer.005.005.xsd". Could this be the issue?
Ashish Shinde
Ranch Hand

Joined: Dec 08, 2002
Posts: 34
Resolved it.

Removed the xml declaration i.e. 1st line , in bindings file.
Ashish Shinde
Ranch Hand

Joined: Dec 08, 2002
Posts: 34

Now facing another issue.
Both xsd have a Type element as follows:
Reviewer.xsd -


Book.xsd


Since TypeCode is defined as element in both xsd's the xjc gives an error as:

[ERROR] A class/interface with the same name "com.impl.TypeCode" is already in use.
Use a class customization to resolve this conflict.
line 14 of file:/C:/work/src/reviewer.005.005.xsd

[ERROR] (Relevant to above error) another "TypeCode" is generated from here.
line 122 of file:/C:/work/src/Book.xsd
Failed to produce code.


Please let me know how i can modify bindings file to implement class customization and make it work?

Thanks in advance


R Srini
Ranch Hand

Joined: Feb 19, 2010
Posts: 215
Ashish, yes, I guess we can't have two different classes with the same name in the same package (in Java) or namespace (in an XSD). So its back to square one then. You will need to put them in different packages. However, I see in the API docs for JAXBContext that we can have multiple packages, colon-delimited, initialized in the same context:Would that help? You can also look at this article.


Manan Panchal
Greenhorn

Joined: Nov 17, 2008
Posts: 24
Hello,
Try this xjb file. This will create two classes ReviewerTypeCode.java and BookTypeCode.java in the same package.

Thanks
Ashish Shinde
Ranch Hand

Joined: Dec 08, 2002
Posts: 34

This works as required.
Thank you very much for the solution.
Ashish Shinde
Ranch Hand

Joined: Dec 08, 2002
Posts: 34
Facing one more issue.
Final xml to generate should have the following format



The Reviewer xsd has a Header complexType as :


The Book.xsd has <Batch> info as follows:

The <Doc>,<Batch> belong to Book.xsd while rest of them, including Header, belong to Reviewer.xsd.
As you can see the <Header> tag occurs at two places. One instance occurs near the root node and other is deep inside.

Have prepared the xjb to generate classes using xjc from both xsd into a single package.
However , when I create the xml structure above and try to marshal, the error thrown is:
unable to marshal type "com.impl.Header" as an element because it is missing an @XmlRootElement annotation]

Is there a way to accomodate this complexType inside the Batch tag?

R Srini
Ranch Hand

Joined: Feb 19, 2010
Posts: 215
Hi. I had this issue, but in a different context. Please see if this helps. It accurately describes the issue, and also you can see some of the questions and responses to the original post.
Ashish Shinde
Ranch Hand

Joined: Dec 08, 2002
Posts: 34
Tried changing the xjb and added parameter "-extension" while using xjc.
But it only changed the setAny(Object) method for Batch in Book.xsd to setAny(Element).

The objectFactory still does not have createHeader(new Header()) method which would return me a JAXBElement to be used in new setAny method.
R Srini
Ranch Hand

Joined: Feb 19, 2010
Posts: 215
And have you looked at this as well? Seems to have a solution. Please check out all the comments and links inside it. The very first answer might be helpful in your case.
Ashish Shinde
Ranch Hand

Joined: Dec 08, 2002
Posts: 34
The problem is I dont have control over xsd.
Is there something that can be implemented through bindings file (xjb) ?
R Srini
Ranch Hand

Joined: Feb 19, 2010
Posts: 215
The answer in the link from my previous post shows two ways of fixing the issue: a) fix the schema, and b) modify your code. You can always use the second approach. Please search for "have to write the following java code to unmarshall and marshall without errors" at this link and you will see the code required to handle it. But I can't help with the bindings file ... maybe someone else can. All the best!
Ashish Shinde
Ranch Hand

Joined: Dec 08, 2002
Posts: 34

Approach to change code did resolve the issue and was able to generate the XML successfully.
However change to xjb would be more cleaner one.

If anybody has any inputs on how to go about it please let me know.
R Srini
Ranch Hand

Joined: Feb 19, 2010
Posts: 215
Nice. Some progress is better than no progress I also found this where they added <xjc:simple/> to the global bindings:
This might work for you.
Manan Panchal
Greenhorn

Joined: Nov 17, 2008
Posts: 24
Please, provide your xsds and xml, so I can try it.
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: JAXB: Two xsd - Create single JAXBContext
 
Similar Threads
JAXB Saving and loading a generic List of type T to/from XML
JAXB in eclipse
SAXParseException: Parsing large XML files with JAXB and StAX
org.springframework.ws.client.WebServiceTransportException: Method Not Allowed [405]
Reading in XML into Objects