Я использую XStream для сериализации и десериализации классов Java в / из XML для интерфейса устройства (NETCONF).До сих пор это работало хорошо, но недавно я столкнулся с блокировщиком.
Существует такой XML, имеющий два элемента с одинаковым именем "a", но разным пространством имен.К сожалению, я ничего не могу сделать с XML-схемой устройства.
<?xml version="1.0" encoding="utf-8"?>
<data>
<a xmlns="http://site1.net/a">
<note>This belongs to namespace 1</note>
</a>
<a xmlns="http://site2.net/a">
<remark>This belongs to namespace 2</remark>
</a>
<b xmlns="http://site1.net/b">
<description>I don't want to create java class for this part</description>
</b>
</data>
Я гуглил, обнаружив, что StaxDriver обязателен для решения проблем с пространством имен, но у меня все еще есть DuplicateFieldException.
Это мои кодыдля теста:
public class XStreamTest {
private static final String FILENAME_DEVICE = "src/test/resources/sample";
@Test
public void test() {
try {
XStream xstream = new XStream(new StaxDriver());
xstream.setClassLoader(Thread.currentThread().getContextClassLoader());
xstream.addPermission(NoTypePermission.NONE);
xstream.addPermission(NullPermission.NULL);
xstream.addPermission(PrimitiveTypePermission.PRIMITIVES);
xstream.allowTypeHierarchy(Collection.class);
xstream.autodetectAnnotations(true);
xstream.ignoreUnknownElements();
xstream.processAnnotations(Data.class);
xstream.allowTypesByWildcard(new String[] {
Data.class.getPackage().getName()+".*"
});
String xml = FileUtils.readFileToString(new File(FILENAME_DEVICE), Charset.defaultCharset());
Data obj = (Data)xstream.fromXML(xml);
ObjectMapper mapper = new ObjectMapper();
System.out.print(mapper.writeValueAsString(obj));
} catch (Exception e) {
e.printStackTrace();
}
}
}
@XStreamAlias("data")
public class Data {
@XStreamAlias("a")
public A1 a;
@XStreamAlias("a")
public A2 a2;
}
@XStreamAlias("a")
public class A1 {
@XStreamAsAttribute
@XStreamAlias("xmlns")
public final String xmlns = "http://site1.net/a";
@XStreamAlias("note")
public String note;
}
@XStreamAlias("a")
public class A2 {
@XStreamAsAttribute
@XStreamAlias("xmlns")
public final String xmlns = "http://site2.net/a";
@XStreamAlias("remark")
public String remark;
}
Это трассировка стека исключений:
com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter$DuplicateFieldException: Duplicate field a2
---- Debugging information ----
message : Duplicate field a2
field : a2
class : dependencies.xstream.Data
required-type : dependencies.xstream.Data
converter-type : com.thoughtworks.xstream.converters.reflection.ReflectionConverter
path : /data/a[2]
line number : 8
version : 1.4.11
-------------------------------
at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter$3.add(AbstractReflectionConverter.java:287)
at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.doUnmarshal(AbstractReflectionConverter.java:457)
at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.unmarshal(AbstractReflectionConverter.java:277)
at com.thoughtworks.xstream.core.TreeUnmarshaller.convert(TreeUnmarshaller.java:72)
at com.thoughtworks.xstream.core.AbstractReferenceUnmarshaller.convert(AbstractReferenceUnmarshaller.java:72)
at com.thoughtworks.xstream.core.TreeUnmarshaller.convertAnother(TreeUnmarshaller.java:66)
at com.thoughtworks.xstream.core.TreeUnmarshaller.convertAnother(TreeUnmarshaller.java:50)
at com.thoughtworks.xstream.core.TreeUnmarshaller.start(TreeUnmarshaller.java:134)
at com.thoughtworks.xstream.core.AbstractTreeMarshallingStrategy.unmarshal(AbstractTreeMarshallingStrategy.java:32)
at com.thoughtworks.xstream.XStream.unmarshal(XStream.java:1487)
at com.thoughtworks.xstream.XStream.unmarshal(XStream.java:1467)
at com.thoughtworks.xstream.XStream.fromXML(XStream.java:1338)
at com.thoughtworks.xstream.XStream.fromXML(XStream.java:1329)
at dependencies.xstream.XStreamTest.test(XStreamTest.java:37)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:538)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:760)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:460)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:206)