I have a given set of classes to unmarshall a xml into an object tree. Now I get a extended xml and want to replace one class in the object tree with an extended version.
XML file
<?xml version="1.0" encoding="UTF-8"?>
<RootNode_001>
<systemId>on the 4</systemId>
<systemName>give me some more</systemName>
<person>
<firstname>James</firstname>
<lastname>Brown</lastname>
<address>
<street>Funky</street>
<city>Town</city>
<type>HOME</type> <!-- this is the new field -->
</address>
</person>
</RootNode_001>
I create a new address class with the new field like this:
public class ExtAddress extends Address {
// inherit from address and add new field
private String type;
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
}
Now I try to unmarshall into an object tree and I expect ExtAddress
to be part of the tree like this:
public class Runner {
public static void main ( String argv[] ) throws Exception {
File file = new File( "basic.xml" );
Class cls = RootNode.class;
// create a context with the root node and the replacement class
JAXBContext jaxbContext = JAXBContext.newInstance( ExtAddress.class, cls );
Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
JAXBElement jaxbElement = unmarshaller.unmarshal( new StreamSource( file ), cls );
RootNode rootNode = (RootNode) jaxbElement.getValue();
System.out.println( rootNode.getClass().getName() );
System.out.println( rootNode.getPerson().getClass().getName() );
// this returns Address but I want ExtAddress
System.out.println( rootNode.getPerson().getAddress().getClass().getName() );
}
}
I use no annotations so far. The unmarshalled object tree return Address
and not ExtAddress
. If I add a XmlType
annotation I get an exception:
@XmlTyp( name = "address" )
ExtAddress extends Address {
...
}
Exception in thread "main" com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException: 1 counts of IllegalAnnotationExceptions
Two classes have the same XML type name "address". Use @XmlType.name and @XmlType.namespace to assign different names to them.
this problem is related to the following location:
at jaxb.standard.Address
at jaxb.ExtAddress
I tried many things but this seems to be very near to a solution. How can I tell jaxb to use an inherited class instead of the original one.
I want to delvier a set of standard classes in a library and be able to change the object tree later as an extension when new fields in xml appear.
See Question&Answers more detail:
os 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…