Java JAXB XJC code generation form XSD schema problem - java

I have my own domain model and corresponding XSD schema for it. It consists of data types and messages that are exchanged in my application. I use XJC tool from Java JRE 1.5 for generation of Java classes for the given XSD schema. The generated classes do not contain neither the serialization/deserialization method nor the validation code. How can I achieve this using JAXB?
Regards

Are you using JAXB 1.x or 2.x?
If 2.x then validation is built in. See this article.
Do you mean that you just want the code to marshall the Bean to XML and unmarshall the XML to a Bean?
There are many articles that show this. Here's an example of marshalling a bean into xml:
JAXBContext jaxb = JAXBContext.newInstance(MyBean.class);
Marshaller marshaller = jaxb.createMarshaller();
java.io.StringWriter sw = new StringWriter();
marshaller.marshal(myBean, sw);
System.out.println(sw.toString());

Related

Jackson completely ignore Jaxb XML related annotations

Imagine a situation when you have a model in Java, and you have to serialize it both to XML and CSV.
I am using Jaxb Marshaller for XML and Jackson's CsvMapper (ObjectMapper) for CSV.
Since the formats are slightly different, I want Jackson's CsvMapper to ignore Jaxb related annotations like #XmlType or #XmlElement. Because Jackson is getting information/considers xml annotations as well and it leads to wrong result.
How can I do it?
This is the way how you probably create new CsvMapper:
CsvMapper csvMapper = new CsvMapper();
csvMapper.findAndRegisterModules();
findAndRegisterModules method invokes findModules which documentation says:
Method for locating available methods, using JDK ServiceLoader facility, along with module-provided SPI.
So, probably you have jackson-module-jaxb-annotations module on class path and this is why CsvMapper recognizes JAXB annotations.
To fix it, you need to remove invocation of this method findAndRegisterModules and register only these modules you needed.

How to Creating Nested xml in Jaxb. I need to create xml as below

I need to create xml as below using jaxb. I know how to create simle xml.But I have no idea regarding this nested xml.Please help me out with this. Thank you all
<whens>
<when>
<whenEntity1_Rule1>
<whenAttribute1_Rule1>
<whenCondition1_Rule1/>
<whenValue1_Rule1>
<literalvalue1_Rule1/>
<whenEntity1_expression1_Rule1/>
<whenAttribute1_expression1_Rule1/>
</whenValue1_Rule1>
</whenAttribute1_Rule1>
<whenAttribute2_Rule1>
<whenCondition2_Rule1/>
<whenValue2_Rule1>
<literalvalue2_Rule1/>
<whenEntity2_expression1_Rule1/>
<whenAttribute2_expression1_Rule1/>
</whenValue2_Rule1>
</whenAttribute2_Rule1>
<whenAttribute3_Rule1>
<whenCondition3_Rule1/>
<whenValue3_Rule1>
<literalvalue3_Rule1/>
<whenEntity3_expression1_Rule1/>
<whenAttribute3_expression1_Rule1/>
</whenValue3_Rule1>
</whenAttribute3_Rule1>
</whenEntity1_Rule1>
</when>
<whens>
You can use an XSD generator to extract the schema that describes the structure you've mentioned above.
You will then be add to add this schema to a JAXB marshaller or unmarshaller to generate JAXB objects and XML that is valid against the above structure. You can see how to do this in the answer to this question.

How to use XSD that includes another XSD with JAXB while XSDs reside in JAR?

I am reading XML files that are validated via XSD files into XJC generated classes. That all works fine when I reference the XSD in the normal file system. Now I want to bundle the XSD into my JAR. That also works fine as long the XSD is standalone with the following code:
//Use the schema factory to get the schema
SchemaFactory sf = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
//Get XSD from JAR
InputStream schemaStream = getClass().getResourceAsStream("/schema/myschema.xsd");
Schema schema = sf.newSchema(new StreamSource(schemaStream));
//parse the XML file and fill the data model
Class<T> c = getXmlDataModelClass();
JAXBContext jaxbContext = JAXBContext.newInstance(c);
m_JaxbUnmarshaller = jaxbContext.createUnmarshaller();
//set the schema to be considered
m_JaxbUnmarshaller.setSchema(schema);
return (T)m_JaxbUnmarshaller.unmarshal(file);
Now the problem: if myschema.xsd includes another XSD:
<xs:include schemaLocation="BaseTypes.xsd"/>
The types in the included XSD are not found.
I also tried to pass an array of two StreamSource with both XSDs into sf.newSchema(), but that did not help.
The easiest is to use URLs, something like (not tested):
URL schemaURL = getClass().getResource("/schema/myschema.xsd");
Schema schema = sf.newSchema(schemaURL);
You'll get a jar:... URL and feed it to the schema factory. As long as included schemas reside in the same JAR, they should be resolved without problems.
For more advanced usage you may instantiate and provide a resource resolver to the schema factory:
sf.setResourceResolver(myResourceResolver);
The resource resolver resolves schemas into resources. You can use something like XMLCatalogResolver to rewrite schema URLs using catalog files, for instance. This would allow you to rewrite absolute URLs into local resources.

Java API for XML Schema manipulation

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

Can JAXB store the class name in the XML so that the the deserialize code doesn't need knowledge of the class?

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.

Categories