I have an xml and and at that XML I have too many child fields such like . From the documentation that I read, I see that JAXB auto generated xml to pojo classes but there is a remark there , JAXB can create fields as well ? I meant do i have to create Employee class and its methods such like String job, String id myself or JAXB will create it themselves ? If my question is not clear, I can provide sample codes.
Cheers
Alper
<code>
<Employee>
<id>121</id>
<name>Alper</name>
</Employee>
</code>
Do I have to create String id; String name; as well ?
You have 2 options:
To create necessary Java classes (e.g. Employee) manually
To use XML schema to generate classes
But XML sample itself is not enough surely.
More information here:
https://docs.oracle.com/javase/tutorial/jaxb/intro/examples.html
you can generate POJO or java class from JAXB in eclipse, command line or maven.
you can file below several tutorials to learn this:
create POJO Class from XSD in Eclipse here
create POJO class from XSD using command line here
create POJO Class from XSD using XJC Maven Plugin here
Related
I have some problems describing my problem.
I have an XML-File with names of existing classes in my project.
E.g.:
<?xml version="1.0" encoding="UTF-8"?>
<MetaClasses>
<MetaClass ID="1">
<Meta>ExistingClassName</Meta>
</MetaClass>
<MetaClass ID="2">
...
</MetaClass>
</MetaClasses>
And i need the corresponding existing class, because i need to work with this class.
I don't want to create a new object, like MetaClass meta = new MetaClass();, i want the real class with its real attributes, properties and methods, since the XML ClassName is just simple text.
I need the properties of that class to proceed my project.
I hope you were able to get my problem correctly or rather i explained it correctly :P
Thank you
I did it by myself.
Maybe someone has the same problem and I could help you with my answer.
I had to take the String inside the <Meta>-Tag and did this:
Class classMeta = Class.forName(string);
Bean beanMeta = (Bean) classMeta.newInstance();
Then I was able to work with this Meta-Class.
Say I have three schemas: main.xsd, common1.xsd, and common2.xsd.
common1 and common2 already have their own predefined packages containing jaxb objects.
main.xsd imports both common1.xsd and common2.xsd.
When I attempt to generate the jaxb objects for main.xsd, it of course generates all of the objects it refers to via common1 and common2, but to the package main which leads to my problem. Now, when I attempt to set data to an element from main containing references to common1 or common2 in the java code, I of course get the error that common1.element does not match main.element.
Ex)
In my java code:
common1.ObjectFactory.getExData() will return common.ExData.
main.setExData(ExDataType exampleData) will expect ExDataType from the package main.
But I get this data from the ObjectFactory in common1, so it refers to common1.ExDataType
My question is, how do I generate these objects for main in a way that I don't duplicate types created in the main package and they instead refer to the existing common1 or common2 objects?
EDIT
Episode files seemed to be the way to go, so I attempted this route.
I first ran the command to generate the episode files for each of my imported schemas using the command supplied by Blaise's answer(but with my filenames/paths substituted):
xjc -d out -episode product.episode Product.xsd
Then I attempted to run the command to generate the JAXB classes for the schema containing these imports using the next command:
xjc -d out ProductPurchaseRequest.xsd -extension -b product.episode
The first command seemed to just generate all of the class files for the "product.xsd" to where I specified in the out parameter, and I don't see an "product.episode" file anywhere.
The second command created a new package for each schema it referenced, then created all of the object classes for them in each, but they all contained the wrong package reference and it was quiet messy.
What am I missing in how I ran these commands?
Below are a couple approaches you can use:
Use External Bindings File to Specify a Complex Type Corresponds to an Existing Class
Below is an example bindings file that associates the complex type named Foo with the existing class com.example.Foo:
<jxb:bindings schemaLocation="yourSchema.xsd">
<jxb:bindings node="//xs:complexType[#name='Foo']">
<jxb:class ref="com.example.Foo"/>
</jxb:bindings>
</jxb:bindings>
Use Episode Files
The above process is quite labour intensive if you have a lot of classes. Instead you can leverage episode files. Episode files can be produced as you generate a class model from an XML Schema. Then when you generate classes from another XML Schema that references the first you can point at the episode file to prevent regenerating the classes.
What is an .episode file..?
I am familiar with JAXB, JAXP and DOM. I know JAXB provides java2xml and xml2java generation(and validation against XML Schema(XSD)). What I want is convenient way to produce XML schema programmatically from scratch. I do not want to produce XSD from java classes. I want to have an object representing the schema itself. For example:
XMLSchemaFactory factory = XMLSchemaFactory.newInstance();
XMLSchema schema = factory.newSchema();
schema.setTargetNameSpace("http://www.example.com");
...
schema.addComplexType(complexTypeElement);
...
schema.addElement(name, type);
...
schema.export(new File("mySchema.xsd"));
I know XML schema is itself XML, so I can use Document, Element, Node and other classes/interfaces from org.w3c.dom, but I wonder is there something more convenient ?
Why I want this - I have some IDL, which I have to translate to WSDL. I have lexer/parser for the IDL and I have convenient representation of it as java objects. Now I want to produce the WSDL using this objects => a lot of XML schemas have to be generated !
From my point use WSDL4J it would be pretty easier for your xml manipulations.
Refer this pdf for more details.
http://wsdl4j.sourceforge.net/downloads/JSR110_proposed_final_draft.pdf
It seems the standard approach for deserializing JAXB XML is to specify the package name when creating the context. Then, JAXB looks up the class based on the root element:
JAXBContext jc = JAXBContext.newInstance("com.foo");
Unmarshaller u = jc.createUnmarshaller();
Object o = u.unmarshal(new StringReader("<?xml version="1.0" encoding="UTF-8" standalone="yes"?><MyJaxb>..."));
I'm looking for a more flexible approach where I don't have to specify the package name and could still deserialize any object. This would be as simple as JAXB storing the package in the XML, but I can't seem to find out how to do this. I can write the code to do it myself but that would be unpleasant. It would like JAXB to do it, if possible. BTW, I am not using schemas, just Annotations and marshal/unmarshal. Any ideas?
Actually you can not deserialize "any" object with pure JAXB. You have to specify either packages (where ObjectFactory.class will be sought) or list of classes like JAXBContext.newInstance(Class1.class, Class2.class, Class3.class); That's how jaxb works, it's a part of agreement.
If your tasks are wider that that, e.g. building java classes from arbitrary xml data structure - it's also possible, but you have to be a bit more concrete - what do you mean under "more flexible approach".
You should be able to add more than one package when you get the instance of the jaxbcontext object. You can add as many packages as you want like below.
JAXBContext jc = JAXBContext.newInstance("com.foo.package1:com.foo.package2" );
however, I am not sure how you are gonna use it if you deserialize it into an Object instance?
Are you not gonna use what you have just deserialized?
Also Unmarshaller is not a thread safe class if your application is a multithreaded one.
I'm using Enunciate to generate a SOAP endpoint for a Wicket web application I am working on and I have a couple of questions that I haven't figured out the solution to yet.
1 How do I change the name of the xsd files? I've looked through the FAQ and it tells me to do something similar to this:
<xml>
<schema namespace="http://api.example.com/data" file="data.xsd"/>
</xml>
However, I haven't quite figured out how to set the targetNamespace for my data objects. I've done this for my service via #WebService ( targetNamespace="blah" ), but how do I annotate my data objects to let Enunciate know which namespace they should belong to?
2 Enunciate generates my XSDs just fine, but I don't particularily like the element names it uses. I have a ServiceRequest and ServiceResponse object. The ServiceRequest object has a List of User objects. The ServiceResponse has a list of Group objects. Enunciate suggests that every "User" object within the ServiceRequest should be using the tag "<users>". I feel that it would make more sense to use the singular form, "<user>" since the tag does in fact only contain a single user. Is it possible to change this behaviour, and if so, how?
Thanks in advance.
So just to be clear, with the exception of the question about naming your schema files, your questions are really more about JAXB than they are about Enunciate. JAXB is the spec that defines how your Java objects are (de)serialized to/from XML and Enunciate conforms to that spec.
Anyway, the easiest way to apply a namespace to your Java objects is with a package-info.java file in the package of your Java classes. Annotate your package with #XmlSchema and set the namespace to be the value you want.
Customizing how your accessors are serialized to/from XML can be done with the #XmlElement annotation, e.g.:
public class MyClass {
...
#XmlElement (name="user")
List<User> users;
...
}
Here are the JAXB javadocs
https://jaxb.dev.java.net/nonav/2.1.9/docs/api/
Or google for a good JAXB tutorial.