Как проанализировать два элемента с одинаковым именем поля, но с другим пространством имен в XML, используя XStream? - PullRequest
0 голосов
/ 19 февраля 2019

Я использую 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)
...