Search code examples
javaandroidsimple-framework

How to create ElementMap without entry?


I need serialize Map object like this with simlexml:

<attributes>
   <name>name1</name>
   <value>value1</value>
   <name>name2</name>
   <value>value2</value>
   <name>name3</name>
   <value>value3</value>
</attributes>

I tried this:

@ElementMap(name = "attributes", key = "name", value = "value", inline = true, required = false)
private HashMap<String, String> attributes;

But result looks like:

   <entry>
      <name>name1</name>
      <value>value1</value>
   </entry>
   <entry>
      <name>name2</name>
      <value>value2</value>
   </entry>
   <entry>
      <name>name3</name>
      <value>value3</value>
   </entry>

Is this possible to create element that i need using simplexml?


Solution

  • As runefist noted, the entry tag will get generated for this type. But what you can do: Customize the (de-)serialization process by using a Converter.

    Here's an example class for serialization:

    @Root(name = "Example")
    public class Example
    {
        @Element
        @Convert(ExampleConverter.class)
        private HashMap<String, String> attributes; // Will use the Converter instead
    
        // ...
    
        public static class ExampleConverter implements Converter<HashMap<String, String>>
        {
            @Override
            public HashMap<String, String> read(InputNode node) throws Exception
            {
                // Implement if needed
            }
    
    
            @Override
            public void write(OutputNode node, HashMap<String, String> value) throws Exception
            {
                value.forEach((k, v) -> {
                    try
                    {
                        node.getChild("name").setValue(k);
                        node.getChild("value").setValue(v);
                    }
                    catch( Exception ex )
                    {
                        // Handle Error
                    }
                });
            }
    
        }
    }
    

    If you also need to deserialize your class, you only have to implement the read() method.

    Finally, don't forget to enable the AnnotationStrategy:

    Serializer ser = new Persister(new AnnotationStrategy());
                                   //  ^^^^^^^^^^^^^^^^^^^^ 
    

    This will generate following output:

    <Example>
       <attributes>
          <name>name2</name>
          <value>value2</value>
          <name>name1</name>
          <value>value1</value>
          <name>name0</name>
          <value>value0</value>
       </attributes>
    </Example>