Reputation: 493
I have a very long XML like :
<Author>
<id></id>
<name></name>
<title></title>
<address></address>
....
</Author>
I'm using JAXB to parser the XML before.
JAXBContext.newInstance(Author.class);
And my Author.java
@XmlRootElement(name = "Author")
public class Author {
private String id;
private String name;
private String title;
private String address;
...
}
It works well but I don't want to parser the whole XML to a big Java bean every time.
So, I want to using below way:
Create Commentator.java
@XmlRootElement(name = "Author")
public class Commentator {
private String id;
private String name;
// setters, getters
}
Create Analyst.java
@XmlRootElement(name = "Author")
public class Analyst {
private String title;
private String address;
// setters, getters
}
And I write below code to test.
JAXBContext context = JAXBContext.newInstance(Analyst.class, Commentator.class);
Unmarshaller unmarshaller = context.createUnmarshaller();
String xml = "<Author> <id>1</id> <name>A</name> <title>B</title> <address>C</address></Author>";
Commentator obj = (Commentator) unmarshaller.unmarshal(new ByteArrayInputStream(xml.getBytes()));
System.out.println(obj);
It will print the correct reslult.
If I want to get the Analyst.
Analyst a = (Analyst) unmarshaller.unmarshal(new ByteArrayInputStream(xml.getBytes()));
I will get the Exception: java.lang.ClassCastException: com.xxx.Commentator cannot be cast to com.xxx.Analyst
I'm not sure this way is correct to parser. But I really need such a func.
Upvotes: 0
Views: 1275
Reputation: 493
Just find a quick way to do this:
JAXBContext context = JAXBContext.newInstance(Analyst.class, Commentator.class);
String xml = "<Author> <id>1</id> <name>A</name> <title>B</title> <address>C</address></Author>";
StreamSource source = new StreamSource(new ByteArrayInputStream(xml.getBytes()));
Unmarshaller unmarshaller = context.createUnmarshaller();
JAXBElement<Analyst> unmarshal = unmarshaller.unmarshal(source, Analyst.class);
And then, get what you want:
Analyst analyst = unmarshal.getValue();
unmarshaller
& source
can't re-use in a method )JAXBElement<Commentator> unmarshal2 = unmarshaller2.unmarshal(source2, Commentator.class);
And then:
Commentator com = unmarshal2.getValue();
No error report and result is correct.
Upvotes: 1
Reputation: 10127
In my opinion it is a somewhat clumsy design to have several Java classes mapped
with the same @XmlRootElement
.
But nevertheless, you are still able to achieve what you want.
You need different JAXBContext
s for Analyst
and Commentator
.
And because a JAXBContext
is a big object and JAXBContext.newInstance(...)
takes quite a long time to execute,
it makes sense to save these JAXBContext
instances in static
variables
and reuse these instead of creating new ones:
private static JAXBContext analystContext;
private static JAXBContext commentatorContext;
if (analystContext == null)
analystContext = JAXBContext.newInstance(Analyst.class);
if (commentatorContext == null)
commentatorContext = JAXBContext.newInstance(Commentator.class);
And consequently you also need different Unmarshaller
s created from them:
Unmarshaller analystUnmarshaller = analystContext.createUnmarshaller();
Unmarshaller commentatorUnmarshaller = commentatorContext.createUnmarshaller();
Then you are able to unmarshal the same XML content to different root classes:
String xml = "<Author> <id>1</id> <name>A</name> <title>B</title> <address>C</address></Author>";
Analyst analyst = (Analyst) analystUnmarshaller.unmarshal(new ByteArrayInputStream(xml.getBytes()));
Commentator commentator = (Commentator) commentatorUnmarshaller.unmarshal(new ByteArrayInputStream(xml.getBytes()));
Upvotes: 1