У меня есть заданный набор классов для демонтажа xml в дерево объектов. Теперь я получил расширенный XML и хочу заменить один класс в дереве объектов на расширенную версию.
XML-файл
<?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>
Я создаю новый класс адресов с новым полем, например:
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;
}
}
Теперь я пытаюсь распаковать в дерево объектов и ожидаю, что ExtAddress
будет частью дерева следующим образом:
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() );
}
}
Пока я не использую аннотации. Демонстрационное дерево объектов возвращает Address
, а не ExtAddress
. Если я добавлю аннотацию XmlType
, я получу исключение:
@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
Я пробовал много вещей, но, похоже, это очень близко к решению. Как я могу сказать jaxb использовать унаследованный класс вместо исходного.
Я хочу получить набор стандартных классов в библиотеке и иметь возможность изменить дерево объектов позже как расширение при появлении новых полей в xml.