1

I have this code:

@ElementList(name="package", required=false, inline=true)   
private Hashtable<String, PackageListItem> packages;

which gives me this error:

D/debug(22150): java.util.Hashtable cannot be cast to java.util.Collection

I tried to fix that using a getter:

@ElementList(name="package", required=false, inline=true)
private Collection<PackageListItem> getPackageXML() {
    return packages.values();
}

but that gives me an error I don't quite understand:

D/debug(22307): Default constructor can not accept read only @org.simpleframework.xml.ElementList(data=false, empty=true, entry=, inline=true, name=package, required=false, type=void) on method 'packageXML' in class com.example.MyClass

I know I can use a ElementMap, but that gives too much information in my XML.

How can I serialize the values of a Hashtable in Simple 2.7.1?

Bart Friederichs
  • 33,050
  • 15
  • 95
  • 195

2 Answers2

0

Alternatively you can use HashMap instead of Hashtable. They are nearly the same, so there is a high chance that it will be suitable for you. Here are the differences: Differences between HashMap and Hashtable?

And here is an example of using maps with simpleXML: http://simple.sourceforge.net/download/stream/doc/tutorial/tutorial.php#map

Update:

Well, Hashtable implements the Map interface, so it should work with the @ElementMap annotation. (You use @ElementList right now.)

Community
  • 1
  • 1
kupsef
  • 3,357
  • 1
  • 21
  • 31
  • I tried using the `@ElementMap` route, but it creates too many elements (each value has its own element, even if `attribute` is set to `true`). – Bart Friederichs Jun 02 '14 at 11:17
0

Try something like that:

private Hashtable<String, PackageListItem> packages;

@ElementList
private List<PackageListItem> list;

public PropertyMap() {
    this.packages = new Hashtable<String, PackageListItem>();
}

@Validate
public void validate() {
    List<String> keys = new ArrayList<String>();

    for(PackageListItem entry : list) {
        String key = entry.getKey();

        if(keys.contains(key)) {
            throw new PersistenceException("Duplicate key %s", key);
        }

        keys.put(key);
    }
}

@Commit
public void build() {
    for(PackageListItem entry : list) {
        packages.put(entry.getKey(), entry);
    }
}
Igor Tyulkanov
  • 5,487
  • 2
  • 32
  • 49
  • The `@Commit` and `@Validate` only get called on construction. The problem is that I construct my object, then change it, then serialize it to XML. On serialization, neither `@Commit` nor `@Validate` methods get called. – Bart Friederichs Jun 02 '14 at 11:16
  • There is a [`@Persist` annotation](http://simple.sourceforge.net/download/stream/doc/javadoc/index.html?org/simpleframework/xml/ElementMap.html) as well, that annotates a method that gets called before serialization of the object. That's where I had to put my code. – Bart Friederichs Jun 02 '14 at 11:55