Java 将映射转换为内联元素,文本XML

Java 将映射转换为内联元素,文本XML,java,android,xml,xml-serialization,simple-framework,Java,Android,Xml,Xml Serialization,Simple Framework,考虑以下地图结构以简化: { "key1": "value1", "key2": "value2" } 使用SimpleXML framework for Java,考虑到映射是父类变量,如何将其转换为以下XML <Parent> <key1>value1</key1> <key2>value2</key2> </Parent> 我已经看过了有关内联映射等的SimpleXML教程,但它还没有找到解

考虑以下地图结构以简化:

{
    "key1": "value1",
    "key2": "value2"
}
使用SimpleXML framework for Java,考虑到映射是父类变量,如何将其转换为以下XML

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

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

据我所知,合适的结构应该是:

<Parent>
  <mapFieldOfTheParentClass>
    <key1>value1</key1>
    <key2>value2</key2>
  </mapFieldOfTheParentClass>
</Parent>
这是因为您的类可能有一个名为key1的字段,并且无法将其与map的key区分开来。但是,如果您确定需要您的结构,那么只要不发生冲突,自定义序列化程序就可以工作

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

在这种情况下,你无法回避这个问题。但幸运的是,这并不复杂

下面是一个例子:

@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.");
        }
    }
}
编辑: 仅映射字段转换器的可能实现:

@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
    }
}

我大体上同意,但我正在与之通信的服务器希望使用我概述的格式。这些消息是显式指定的,因此冲突/重复密钥是我的实现的错误结果。谢谢,谢谢你。只能将转换应用于示例的成员值,而不能应用于整个类。我宁愿只处理那个领域。还有,我问的是关于连载的问题,但我能找出另一面。谢谢。您可以这样做,只需为该字段的类型实现一个转换器,添加@Convert。。。和@Element注释。但对于阅读来说,这可能很难实现。但如果你只想写“对不起”,那就误读你的问题吧,它会起作用的。提示:转换器将为映射创建一个包装器元素。要解决这个问题,只需将其修改为第一个值并删除class属性。如果您遇到麻烦,请在这里报告。我添加了一个示例,说明如何实现仅写转换器。
@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
    }
}