Search code examples
javaxml-serializationsimple-framework

Simple XML: suppress length attribute in serialized arrays


Take a class member like this one:

@ElementArray
private String[] names;        

Simple XML will serialize this as:

<names length="3">
   <string>Jonny Walker</string>
   <string>Jack Daniels</string>
   <string>Jim Beam</string>
</names>

Is there any way I can suppress the length attribute for the enclosing element?


Solution

  • There doesn’t seem to be a straightforward way to do it (see issue #39), but a hack will do the trick: Lists can be inlined (so only the elements for the items will be added, without the enclosing element and its unwanted attribute). You can then add a “pristine” enclosing element with a @Path annotation. Arrays cannot be inlined directly, but you can convert them to lists.

    • Write a getter which returns the array as a List.
    • Annotate the getter as @ElementList(inline=true) and @Path("names").
    • If you have added the @Default annotation, annotate the array as @Transient so it won’t get serialized twice.

    Like this:

    @Transient
    private String[] names;
    
    @ElementList(inline=true)
    @Path("names")
    public List<String> getNamesAsList() {
        if (names == null)
            return null;
        else
            return Arrays.asList(names);
    }
    

    Which will then yield:

    <names>
       <string>Jonny Walker</string>
       <string>Jack Daniels</string>
       <string>Jim Beam</string>
    </names>
    

    You’ll have to add some extra magic for de-serialization, likely constructor injection. (Since in my case the array is final, I will need that anyway.)

    If you require de-serialization, you will need to de-serialize the exact same elements you serialized. That is, @ElementList(inline=true) @Path("names") will work whereas e.g. @ElementList(name="names") will throw a validation error.