【问题标题】:Simple xml framework deserializing with multiple element names使用多个元素名称反序列化的简单 xml 框架
【发布时间】:2013-11-09 14:47:26
【问题描述】:

我正在尝试使用 Simple XML Framework 将公共 Web 服务中的一些 xml 数据序列化为 java 对象。 问题是来自服务的不同方法返回具有不同元素名称的相同概念。例如,方法 A 像这样返回元素 foo

<data><Foo>foo value</Foo></data>

而方法B返回

<data><foo>foo value</foo></data>

方法 C 返回

<data><FOO>foo value</FOO></data>

有没有办法(多名称注释等)将此 xml 反序列化为同一个类和同一个元素?例如,将三个方法的结果反序列化为三个不同“Foo”对象中的相同“foo”元素(每个方法一个):

@Root(name="data")
public class Foo{
    @Element
    public String foo;
    (...)
}

【问题讨论】:

    标签: java xml xml-deserialization simple-framework


    【解决方案1】:

    很遗憾,您不能为每个字段设置多个注释,@Element 仅支持一个名称(区分大小写)。 作为替代方案,您可以自行反序列化这些字段 - 以下是如何执行此操作的示例:

    @Root(name = "data")
    @Convert(FooConverter.class) // Set the converter that's used for serializing / deserializing this class
    public class Foo
    {
        @Element( name = "foo") // For this solution it doesn't matter what you set here
        public String foo;
    
        // ...
    
    
        /*
         * The converter - Implement the serialization / deserialization here.
         * You don't have to use an inner class here.
         */
        public static class FooConverter implements Converter<Foo>
        {
            @Override
            public Foo read(InputNode node) throws Exception
            {
                Foo f = new Foo();
                InputNode nextNode = node.getNext();
    
                while( nextNode != null )
                {
                    if( nextNode.getName().equalsIgnoreCase("foo") ) // Here you pick-up the node, however it's written
                    {
                        f.setFoo(nextNode.getValue());
                    }
    
                    nextNode = node.getNext();
                }
    
                return f;
            }
    
    
            @Override
            public void write(OutputNode node, Foo value) throws Exception
            {
                // Not required in this example.
                throw new UnsupportedOperationException("Not supported yet.");
            }
    
        }
    }
    

    使用示例:

    String str = "<data><foo>foo value</foo></data>"; // Foo can be written as you like
    
    Serializer ser = new Persister(new AnnotationStrategy()); // Setting the AnnotationStrategy is important!!
    Foo f = ser.read(Foo.class, str);
    
    System.out.println(f);
    

    现在foo 写成foo 还是FoO 都没有关系——只要它是一个foo。

    【讨论】:

    • 非常感谢!有用!还有一个问题......我是否必须通过转换器的读取方法序列化 Foo 上的所有其他属性,或者我可以以某种方式回退到这些属性的默认序列化?
    • 在您的转换器中,您可以使用 Serializer / Persister 反序列化单个字段;例如。 new Persister().read(FieldClass.class, node) 是可能的。您还可以为每个字段设置一个Converter!但我想(我不是 100% 确定),你不能为整个班级设置一个转换器,它只管理一个字段。在您的情况下,仅为foo 字段设置转换器将是最佳解决方案。但由于它的名称不是恒定的,因此查找将只对具有正确名称的那些字段使用转换器。
    • 也许您可以在Persister 的构造函数中设置的类可以在这里为您提供更多帮助。阅读他们的文档是个好主意,可能他们可以提供您需要的行为。
    猜你喜欢
    • 2011-11-20
    • 1970-01-01
    • 2020-03-13
    • 2016-09-12
    • 2017-02-07
    • 1970-01-01
    • 1970-01-01
    • 2020-01-14
    • 1970-01-01
    相关资源
    最近更新 更多