views:

183

answers:

1

My question is close to this one: Digester: Extracting node name

Even with the answer, I can't find out.

Here is my xml file (from smartgwt RestDataSource POST):

<data>
  <isc_OID_14>
    <attribute1>value1</attribute1>
    <attribute2>value2</attribute2>
  </isc_OID_14>
</data>

I would like to create, with Commons Digester, the following map : {attribute1=value1, attribute2=value2}

I already have those lines:

digester = new Digester();
digester.addObjectCreate("data", HashMap.class);
// some "put" rules matching something like data/*
return digester.parse(myFile);

I do not know the list nor the name of tags in the <data><sourceId /></data>. isc_OID_14 or attribute1 can be named foobar or id or attribute335...

+2  A: 

I think something like this is what you want:

import java.io.*;
import java.util.*;
import org.apache.commons.digester.*;

public class DigestToMap {
    @SuppressWarnings("unchecked")
    public static void main(String[] args) throws Exception {
        File file = new File("digestme.xml");
        Digester digester = new Digester();
        digester.setRules(new ExtendedBaseRules());
        digester.addObjectCreate("data", HashMap.class);
        digester.addRule("data/?", new Rule() {
            @Override public void end(String nspace, String name) {
                ((HashMap<String,String>)getDigester().peek()).put("[ID]", name);
            }
        });
        digester.addRule("*", new Rule() {
            @Override public void body(String nspace, String name, String text) {
                ((HashMap<String,String>)getDigester().peek()).put(name, text);
            }
        });
        Map<String,String> map = (Map<String,String>) digester.parse(file);
        System.out.println(map);
    }
}

Basically it uses ExtendedBaseRules for the wildcard matching.

There are 3 rules:

  • On data, ObjectCreate a HashMap
  • On data/? (direct child of data), map [ID]=name (make this Rule a no-op if not needed)
  • On * (everything else), map name=text

On my machine, this prints:

{[ID]=isc_OID_14, attribute1=value1, attribute2=value2}

API links

polygenelubricants
You are late but efficient ^^ greatful thanks!
enguerran