Android Is it possible to define a map in an XML file?

23,574

Solution 1

How can I define a map in XML?

<thisIsMyMap>
  <entry key="foo">bar</entry>
  <entry key="goo">baz</entry>
  <!-- as many more as your heart desires -->
</thisIsMyMap>

Put this in res/xml/, and load it using getResources().getXml(). Walk the events to build up a HashMap<String, String>.

Solution 2

A simpler option would be to use two arrays. This has the benefit of not iterating the xml file again, uses less code and its more straight forward to use arrays of different types.

<string-array name="myvariablename_keys">
   <item>key1</item>
   <item>key1</item>
</string-array>

<string-array name="myvariablename_values">
   <item>value1</item>
   <item>value2</item>
</string-array>

Then your java code would look like this:

String[] keys = this.getResources().getStringArray(R.array.myvariablename_keys);
String[] values = this.getResources().getStringArray(R.array.myvariablename_values);
LinkedHashMap<String,String> map = new LinkedHashMap<String,String>();
for (int i = 0; i < Math.min(keys.length, values.length); ++i) {
   map.put(keys[i], values[i]);
}

Solution 3

You can always embed Json inside your strings.xml file:

res/values/strings.xml

<string name="my_map">{"F":"FOO","B":"BAR"}</string>

And inside your Activity, you can build your Map in the onStart method:

private HashMap<String, String> myMap;

@Override
protected void onStart() {
    super.onStart();
    myMap = new Gson().fromJson(getString(R.string.my_map), new TypeToken<HashMap<String, String>>(){}.getType());
}

This code needs Google Gson API to work. You can do it using the built-in Json API in the Android SDK.

And As for accessing the Map statically, you can create a static method:

private static HashMap<String, String> method(Context context) {
    HashMap<String, String> myMap = new Gson().fromJson(context.getString(R.string.serve_times), new TypeToken<HashMap<String, String>>(){}.getType());
    return myMap;
}

Solution 4

The correct answer was mentioned by CommonsWare above, but as XML-parsing is not so simple, as following a simple parser for this purpose:

public static Map<String, String> getHashMapResource(Context context, int hashMapResId) {
    Map<String, String> map = new HashMap<>();
    XmlResourceParser parser = context.getResources().getXml(hashMapResId);

    String key = null, value = null;

    try {
        int eventType = parser.getEventType();

        while (eventType != XmlPullParser.END_DOCUMENT) {
            if (eventType == XmlPullParser.START_TAG) {
                if (parser.getName().equals("entry")) {
                    key = parser.getAttributeValue(null, "key");

                    if (null == key) {
                        parser.close();
                        return null;
                    }
                }
            }
            else if (eventType == XmlPullParser.END_TAG) {
                if (parser.getName().equals("entry")) {
                    map.put(key, value);
                    key = null;
                    value = null;
                }
            } else if (eventType == XmlPullParser.TEXT) {
                if (null != key) {
                    value = parser.getText();
                }
            }
            eventType = parser.next();
        }
    } catch (Exception e) {
        e.printStackTrace();
        return null;
    }
    return map;
}
Share:
23,574
ilomambo
Author by

ilomambo

I have a solid programming education. Trying to learn how everything works and interacts. Hopefully, to write great applications.

Updated on February 10, 2022

Comments

  • ilomambo
    ilomambo about 2 years

    I was trying to define a static hash table that makes use of resources, but I got stonewalled by the impossibility of accessing resources statically.

    Then I realized that the best of all places to define a static map is in the resources files themselves.

    How can I define a map in XML? I believe that if possible it should be similar to the Listpreference mechanism, with entries and entries-values.