我尝试使用MOXy完成此question中描述的内容。 但我有一些不同的行为,但结果是一样的。它不起作用。
我使用@XmlElements,对于每个concret类,我添加了一个名称和类型的@XmlElement。 对于没有适配器的所有类,它都是完美的,但不适用于使用PolyAdapter的类。
在我的情况下,将调用适配器来封送对象。但它写的所有内容都是这样的条目到xml文件中。
<?xml version="1.0" encoding="UTF-8"?>
<fooContainer>
<poly PolyName="PolyN$1">ABCBCD</poly>
<cPlexPoly>moxy.CPlexPoly$CPlexPolyAdapter$CCPWrapper@480bdb19</cPlexPoly>
</fooContainer>
根本不会召唤unmarshaller。
我在两种情况下测试了MOXy 2.5.0和当前的RC3 2.5.1,结果是相同的。 我也启用了调试输出,没有警告或错误。
或许还有另一种方法可以实现这个目标
更新1:提供型号
我创建了一个显示我的MOXy 2.5.0问题的小例子
接口:
@XmlRootElement
public interface Foo {
public List<String> getCoordinates();
}
没有XmlAdapter的类:
@XmlRootElement(name="poly")
public class Poly implements Foo {
@XmlAttribute
String PolyName = "PolyN$1";
@XmlAnyElement
private List<String> coordinates = new LinkedList<>();
@Override
public List<String> getCoordinates() {
return coordinates;
}
public void addCoordinate( final String poly ) {
coordinates.add( poly );
}
}
使用XmlAdapter的类:
@XmlJavaTypeAdapter(CPlexPolyAdapter.class)
public class CPlexPoly implements Foo {
private Map<String, String> values = new HashMap<>();
@Override
public List<String> getCoordinates() {
return new ArrayList<>(values.values());
}
public void addCoordinate( final String poly ) {
values.put( Integer.toString( poly.hashCode()), poly );
}
public List<String> getKeys() {
return new ArrayList<>(values.keySet());
}
public static class CPlexPolyAdapter extends XmlAdapter<CCPWrapper, CPlexPoly> {
@XmlRootElement(name="wrapper")
public static class CCPWrapper {
@XmlAnyElement
List<String> keys = new ArrayList<>();
@XmlAnyElement
List<String> values = new ArrayList<>();
}
@Override
public CPlexPoly unmarshal(CCPWrapper v) throws Exception {
// Won't be called.
return null;
}
@Override
public CCPWrapper marshal(CPlexPoly v) throws Exception {
if( v == null ) {
return null;
}
CCPWrapper wrapper = new CCPWrapper();
wrapper.values.addAll( v.getCoordinates() );
wrapper.keys.addAll( v.getKeys() );
return wrapper;
}
}
}
简单容器类:
@XmlRootElement(name="fooContainer")
public class FooContainer {
@XmlElements({
@XmlElement(name = "poly", type = Poly.class),
@XmlElement(name = "cPlexPoly", type = CPlexPoly.class)
})
public List<Foo> container = new LinkedList<>();
}
主:
public class Main {
public static void main(String[] args) {
FooContainer fc = new FooContainer();
Poly poly = new Poly();
poly.addCoordinate("ABC");
poly.addCoordinate("BCD");
CPlexPoly cpoly = new CPlexPoly();
cpoly.addCoordinate("XYZ");
cpoly.addCoordinate("WXY");
fc.container.add( poly );
fc.container.add( cpoly );
/* Marshall */
JAXBContext context;
try {
context = JAXBContext.newInstance( FooContainer.class );
Marshaller marshaller = context.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal( fc, new FileWriter("fc.xml") );
}
catch (JAXBException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
/* UnMarshall */
}
}
我还更新了上面描述的结果。 THX。
更新2:简化包装
即使这个简单的包装器只包含一个属性,也没有任何变化。
@XmlJavaTypeAdapter(CPlexPolyAdapter.class)
public class CPlexPoly implements Foo {
private Map<String, String> values = new HashMap<>();
@Override
public List<String> getCoordinates() {
return new ArrayList<>(values.values());
}
public void addCoordinate( final String poly ) {
values.put( Integer.toString( poly.hashCode()), poly );
}
public List<String> getKeys() {
return new ArrayList<>(values.keySet());
}
public static class CPlexPolyAdapter extends XmlAdapter<CCPWrapper, CPlexPoly> {
@XmlRootElement(name="wrapper")
public static class CCPWrapper {
@XmlAttribute
String test = "test";
}
@Override
public CPlexPoly unmarshal(CCPWrapper v) throws Exception {
// Won't be called.
return null;
}
@Override
public CCPWrapper marshal(CPlexPoly v) throws Exception {
if( v == null ) {
return null;
}
CCPWrapper wrapper = new CCPWrapper();
return wrapper;
}
}
}
因此,如果有人知道出了什么问题,那将非常有帮助。 谢谢 基督教
答案 0 :(得分:1)
注意:我是EclipseLink JAXB (MOXy)主管,是JAXB (JSR-222)专家组的成员。
您遇到的问题是由于CCPWrapper
类未正确映射。您不能使用@XmlAnyElement
映射两个字段/属性。
@XmlRootElement(name = "wrapper")
public static class CCPWrapper {
@XmlAnyElement
List<String> keys = new ArrayList<>();
@XmlAnyElement
List<String> values = new ArrayList<>();
}
当我修改代码以删除其中一个@XmlAnyElement
注释时,一切似乎都正常工作。
感谢您的回答。但不,我仍然得到相同的输出。我什至 使用XmlAnyElement注释删除了两个列表,并添加了一个 简单的XmlAttribute。输出不会改变。查看更新 有问题的包装类。
我刚刚注意到,当我尝试使用代码时,我已将CPlexPoly
类型的字段添加到FooContainer
类。除了我之前的建议之外,还会将XmlAdapter
应用于container
字段。
import java.util.*;
import javax.xml.bind.annotation.*;
@XmlRootElement(name = "fooContainer")
public class FooContainer {
@XmlElement
private final CPlexPoly workaround = null;
@XmlElements({
@XmlElement(name = "poly", type = Poly.class),
@XmlElement(name = "cPlexPoly", type = CPlexPoly.class)
})
public List<Foo> container = new LinkedList<>();
}
您可以采取与解决方法类似的方法。我打开了以下错误,您可以使用它来跟踪我们在实际修复方面的进展:
更好的解决方法是在用于创建CCPWrapper
的类中包含JAXBContext
类,如下所示:
context = JAXBContext.newInstance( FooContainer.class, CCPWrapper.class );