how to use jaxb to create java objects - java

I am trying to create java objects from xml file. I am using jaxb(unmarshalling) to create java objects.I am getting errors javax.xml.bind.UnmarshalException: unexpected element (uri:"http://www.w3.org/2001/XMLSchema", local:"schema"). Expected elements are
I did some google and found out that, we need xsd file to do that... so I converted it to xsd using apache inst2xsd tool. I am using following java code:
import java.io.FileNotFoundException;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.UnmarshalException;
import javax.xml.bind.Unmarshaller;
import javax.xml.bind.annotation.XmlRootElement;
#XmlRootElement(name="report")
public class Report
{
public static void main(String [] args) throws FileNotFoundException
{
try
{
JAXBContext jc = JAXBContext.newInstance(new Class[] {com.bcbsks.testjb.Report.class});
Unmarshaller um = jc.createUnmarshaller();
Report myJAXBObject = (Report)um.unmarshal(new java.io.FileInputStream("report.xsd"));
}
catch( UnmarshalException ue )
{
ue.printStackTrace();
}
catch( JAXBException je )
{
je.printStackTrace();
}
}
}
But I am getting fol;owing error:
javax.xml.bind.UnmarshalException: unexpected element (uri:"http://www.w3.org/2001/XMLSchema", local:"schema"). Expected elements are (none)
Can you please tell me whats wrong I am doing?
Any help is greatly appreciated.

I think you are missing a few steps. You didn't post what report.xsd is, nor a sample xml, so I'm going to take a few guesses.
For starters, you are trying to unmarshal the xsd and not xml, which is itself the root of the problem. That being said, your Report.java class does not look properly generated so it is unlikely that your unmarshalling would work even if you tried against your xml file.
If you have a properly created XSD file, the first thing you should do is create the JaxB POJOs using xjc. xjc comes installed with java, and you use it to create annotated java classes from the xsd. It will also create 2 additional files - ObjectFactory.java and package-info.java which are used by JAXB. (You can specify the output path using the -d param (see --help for the full list of switches)
xjc -d c:\dev\myproject\src\main\java report.xsd
Once you have those files generated, you have to create your JAXBContext based on that package/file.
JAXBContext jc = JAXBContext.newInstance(something.generated.Report.class);
Unmarshaller um = jc.createUnmarshaller();
Report myJAXBObject = (Report)um.unmarshal(new java.io.FileInputStream("report.xsd"), Report.class).getValue();
The unmarshaller generates a JAXBElement, from which you can extract the actual report class.
Hope this helps.

There are no properties on the bean you are trying to unmarshal. But more importantly, you are trying to deserialize your object from the XSD itself. The error message is a good indicator here:
unexpected element (uri:"http://www.w3.org/2001/XMLSchema", local:"schema")
JAXB is spitting out this error message because it is attempting to map the XSD's metadata to properties of your bean. Which of course, your bean doesn't actually have any. The next part of the error message indicates as much:
Expected elements are (none)
You need to define your Java Bean properly (put some properties on it!), and actually get an XML file that represents the serialized version of your bean.

Related

How to stop JAXB from escaping certain characters when converting java class to XML String? [duplicate]

This question already has answers here:
How to generate CDATA block using JAXB?
(10 answers)
JAXB Marshalling Unmarshalling with CDATA
(7 answers)
Closed 2 years ago.
I have run into a few issues in my Java 1.8 application when trying to use JAXB to marshal my Java object into an XML string. The first issue was that by default marshalling escapes < and > so when i was trying to wrap some fields in
<![CDATA[ my-field-value ]]>
it was being turned into
<![CDATA[ my-field-value ]]>
Which breaks functionality of using CDATA in the first place. I used a custom character handler according to some comments from How to prevent JAXB escaping a string. Everything is working for me now but i have heard that im not supposed to use com.sun.xml.internal.* packages and currently I am doing so like this (notice the use of internal):
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
JAXBContext jc = JAXBContext.newInstance(MyClass.class);
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
marshaller.setProperty(
"com.sun.xml.internal.bind.marshaller.CharacterEscapeHandler",
new MyCustomCharacterHandler());
return marshaller;
Where MyCustomCharacterHandler is declared like so (note the use of internal):
import com.sun.xml.internal.bind.marshaller.CharacterEscapeHandler;
public class XmlCdataCharacterHandler implements CharacterEscapeHandler {
...
}
This combination is working fine for me but when modifying my code to get rid of .internal.* like so using this dependency:
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-core</artifactId>
<version>2.2.7</version>
</dependency>
import com.sun.xml.bind.marshaller.CharacterEscapeHandler;
public class XmlCdataCharacterHandler implements CharacterEscapeHandler {
...
}
JAXBContext jc = JAXBContext.newInstance(PrintPack.class);
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
marshaller.setProperty(
"com.sun.xml.bind.marshaller.CharacterEscapeHandler",
new MyCustomCharacterHandler());
return marshaller;
My server will no longer start and is getting a JAXBException with the following message:
name: com.sun.xml.bind.marshaller.CharacterEscapeHandler value: com.fmrco.research.search.handlers.MyCustomCharacterHandler#1f3d4305
Which makes me think that my custom handler which implements the CharacterEscapeHandler is no longer being used correctly. Does anyone know how to fix this so i can keep this implementation while avoiding com.sun.xml.internal.* packages? Is there a better/newer way to turn a java class into an XML string? Seems like I should not be stuck on this for as long as I have been. Thank you!

JAXBException : no package name is given

for XML File parsing I am using JAXB but after compilation following error is reported
javax.xml.bind.JAXBException: No package name is given
at javax.xml.bind.ContextFinder.find(Unknown Source)
at javax.xml.bind.JAXBContext.newInstance(Unknown Source)
at javax.xml.bind.JAXBContext.newInstance(Unknown Source)
at javax.xml.bind.JAXBContext.newInstance(Unknown Source)
at searchAlgo.Question.<init>(Question.java:16)
code is given below
import java.io.File;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
public class Question {
//String question = new String() ;
String s = new String();
Question()
{
try{
File file = new File("C:\\Users\\Username\\Documents\\levels.xml");
JAXBContext jaxbContext = JAXBContext.newInstance(s);
Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
String string = (String) jaxbUnmarshaller.unmarshal(file);
System.out.println(string);
}
catch(JAXBException e){
e.printStackTrace();
}
}}
do I need to install JAXB plug-in?
i am using jdk 1.8.0_91 and eclipse mars
Your problem is that you're not using JAXB correctly.
First,
JAXBContext jaxbContext = JAXBContext.newInstance(s);
is wrong because JAXBContext.newInstance(...) is expecting either a class or " separated java package names that contain schema-derived classes and/or fully qualified JAXB-annotated classes" according to documentation
The point is to determine what kind of objects JAXB is dealing with. In other words, it will be what kind of objects you have inside C:\\Users\\Username\\Documents\\levels.xml XML file.
Second,
if you want to unmarshall objects from XML file or marshall objects to String, I suggest you read the following documentation with a lot of examples:
Marshaller
Unmarshaller
JAXBContext.newInstance() expects either a Class or a package name. Since s is a String, it is interpreted as a package name. But your String is empty, so you get "No package name is given"

Marshalling fails with exception about MarshallerImpl not known to this context

I have a relatively simple package of 8 Java classes generated from an XML schema using JAXB XJC. I also have a utility class to marshal and unmarshal instances of the class.
This works
The utility class can successfully unmarshal a valid XML document into an instance of the ‘root’ class WordMergeInfo. For example this works fine:
JAXBContext jc = JAXBContext.newInstance(WordMergeInfo.class);
Unmarshaller um = jc.createUnmarshaller();
return (WordMergeInfo)um.unmarshal(inputStream);
This doesn’t work
But marshalling to a string fails. In this code:
JAXBContext jc = JAXBContext.newInstance(WordMergeInfo.class);
Marshaller m = jc.createMarshaller();
StringWriter writer = new StringWriter();
m.marshal(m, writer);
return writer.toString();
the call to Marshaller.marshal fails with the following error:
javax.xml.bind.JAXBException: class com.sun.xml.bind.v2.runtime.MarshallerImpl nor any of its super class is known to this context.
at com.sun.xml.bind.v2.runtime.JAXBContextImpl.getBeanInfo(JAXBContextImpl.java:594)
at com.sun.xml.bind.v2.runtime.XMLSerializer.childAsRoot(XMLSerializer.java:482)
at com.sun.xml.bind.v2.runtime.MarshallerImpl.write(MarshallerImpl.java:315)
at com.sun.xml.bind.v2.runtime.MarshallerImpl.marshal(MarshallerImpl.java:244)
As I understand it, nor any of its super class is known to this context means that a JAXB class needed for marshalling cannot be found. So why can’t one of the JAXB implementation classes be found, when the same class is in the stack trace?
Context
This error showed up in a unit test of my class, run under Maven. The dependencies are:
javax.xml.bind:jaxb-api:2.1
com.sun.xml.bind:jaxb-impl:2.1.13
I got the same error with earlier versions of these (2.0 and 2.0.3, respectively).
The Maven test class path is:
C:\Users\mstra.CUSTMAN\Workspace\DARTCorrModule\xml\target\test-classes
C:\Users\mstra.CUSTMAN\Workspace\DARTCorrModule\xml\target\classes
C:\Users\mstra.CUSTMAN\.m2\repository\javax\xml\bind\jaxb-api\2.1\jaxb-api-2.1.jar
C:\Users\mstra.CUSTMAN\.m2\repository\javax\xml\stream\stax-api\1.0-2\stax-api-1.0-2.jar
C:\Users\mstra.CUSTMAN\.m2\repository\javax\activation\activation\1.1\activation-1.1.jar
C:\Users\mstra.CUSTMAN\.m2\repository\com\sun\xml\bind\jaxb-impl\2.1.13\jaxb-impl-2.1.13.jar
C:\Users\mstra.CUSTMAN\.m2\repository\junit\junit\4.8.2\junit-4.8.2.jar
C:\Users\mstra.CUSTMAN\.m2\repository\org\mockito\mockito-all\1.8.5\mockito-all-1.8.5.jar
C:\Users\mstra.CUSTMAN\.m2\repository\javax\ejb\ejb-api\3.0\ejb-api-3.0.jar
C:\Users\mstra.CUSTMAN\.m2\repository\org\slf4j\slf4j-api\1.6.4\slf4j-api-1.6.4.jar
Any insight is appreciated.
nor any of its super class is known to this context
This means that the class is not registered as a marshallable class in the JAXB context.
Your error is on this line:
m.marshal(m, writer);
You are trying to marshal the marshaller itself. You probably meant to marshal a WordMergeInfo object.

How to export java JAXB Schema class to an xsd file?

I'm running into a problem with some XML validation and am trying to debug my problem. I am generating my XSDs on the fly with JAXBContext.generateSchema(), and then creating a unified schema with SchemaFactory.newSchema(schemas). However, my validation is failing. I'd like to see if the unified schema that newSchema is creating is as I expect, however I cannot seem to find a way to export the resulting Schema class to a string or a text file.
Is there any way to export a javax.xml.validation.Schema class into a readable String and/or XSD file? I looked through the API and cannot seem to find anything.
Thanks,
Eric
Instead of combining your schemas after creating them from JAXBContext.generateSchema(), why not just generate them all at once from your JAXBContext.
JAXBContext jc = JAXBContext.newInstance( new Class[] { Class1.class,
Class2.class,
Class3.class
}
);
jc.generateSchema(new SchemaOutputResolver() {
#Override
public Result createOutput(String namespaceUri, String suggestedFileName) throws IOException {
File file = new File(suggestedFileName);
return new StreamResult(file);
}
});

Can I replace jaxb.properties with code?

I am using some non-standard extensions from EclipseLink's implementation of JAXB, and to enable that implementation, I have to configure it using jaxb.properties. Works well.
However, due to a build error, the properties file was not included in the proper place, resulting in the default JAXB being used, which without any errors just continued to parse the XML file, ignoring the non-standard extension, leaving me with a non-working bean.
To make this more robust, I'd like to get rid off the properties file and specify the context configuration in code. I already have a compile-time dependency on EclipseLink because of their annotations, and I do not need this part configurable at deploy time (in fact, seeing what can go wrong, I do not want it configurable).
You could do the following to get an EclipseLink JAXB (MOXy) JAXBContext without a jaxb.properties file:
import java.io.File;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import org.eclipse.persistence.jaxb.JAXBContextFactory;
public class Demo {
public static void main(String[] args) throws Exception {
//JAXBContext jc = JAXBContext.newInstance(Animals.class);
JAXBContext jc = JAXBContextFactory.createContext(new Class[] {Animals.class}, null);
Unmarshaller unmarshaller = jc.createUnmarshaller();
File xml = new File("src/forum6871469/input.xml");
Animals animals = (Animals) unmarshaller.unmarshal(xml);
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(animals, System.out);
}
}

Categories

Resources