将Map转换为内联元素,文本XML

时间:2015-02-19 13:01:23

标签: java android xml xml-serialization simple-framework

考虑以下Map结构(简化为JSON):

{
    "key1": "value1",
    "key2": "value2"
}

使用Java的SimpleXML框架,考虑到map是Parent的类变量,我如何转换为以下XML。

<Parent>
  <key1>value1</key1>
  <key2>value2</key2>
</Parent>

我已经看过围绕内联映射等的SimpleXML教程,但它没有解决方案。我想我需要实现某种自定义序列化器。 ?

2 个答案:

答案 0 :(得分:0)

据我所知,正确的结构应该是:

<Parent>
  <mapFieldOfTheParentClass>
    <key1>value1</key1>
    <key2>value2</key2>
  </mapFieldOfTheParentClass>
</Parent>

那是因为你的类可能有一个名为“key1”的字段,并且不可能将它与map的键区分开来。但是,如果你确定你想要你的结构,只要不发生冲突就可以使用自定义序列化器。

答案 1 :(得分:0)

  

我需要实现某种自定义序列化器。

在这种情况下,你不会解决这个问题。但幸运的是,它并不复杂。

以下是一个例子:

@Root(name = "Parent")
@Convert(Example.ParentConverter.class)
public class Example
{
    private Map<String, String> values;

    // ...

    static class ParentConverter implements Converter<Example>
    {

        @Override
        public Example read(InputNode node) throws Exception
        {
            Example value = new Example();
            value.values = new HashMap<>();
            InputNode next;

            while( ( next = node.getNext() ) != null )
            {
               value.values.put(next.getName(), next.getValue());
            }

            return value;
        }

        @Override
        public void write(OutputNode node, Example value) throws Exception
        {
            // Implement to support writing too
            throw new UnsupportedOperationException("Not supported yet.");
        }
    }
}

@Convert需要例如。 AnnotationStrategy

Serializer ser = new Persister(new AnnotationStrategy());
Example e = ser.read(Example.class, xml); // xml = input xml

编辑:

仅适用于map-field的转换器的可能实现:

@Override
public void write(OutputNode node, Map<String, String> value) throws Exception
{
    final OutputNode parent = node.getParent();

    if( !value.isEmpty() )
    {
        boolean first = true;

        for( Map.Entry<String, String> e : value.entrySet() )
        {
            if( first == true )
            {
                node.setName(e.getKey());
                node.setValue(e.getValue());
                // Remove generated 'class' attribute for collections
                node.getAttributes().remove("class");
                first = false;
            }
            else
            {
                parent.getChild(e.getKey()).setValue(e.getValue());
            }
        }
    }
    else
    {
        // Handle empty maps
    }
}