Here is a class I wrote to parse an xml plist file. It uses the XmlPullParser to do the parsing. I have only implemented what I needed for my project. But this should get you started for extending the class if you need more than what this class provides.
File : XMLPropertyListConfiguration.java
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package com.example.plist;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Stack;
import org.xmlpull.v1.XmlPullParser;
import android.annotation.SuppressLint;
import android.util.Xml;
//import android.util.Log;
/**
* This class will parse a plist xml file and store the contents in a
* hierarchical HashMap of tuples, where the Object value could
* be another HashMap, an ArrayList, Boolean, Date, String or Integer value.
*
* Use the getConfiguration methods to retrieve the values from the parsed plist
* file.
*
* The key names for nested dictionary references must be of the form :
* Dict1KeyName.Dict2KeyName.ElementKeyName
*
* @author akoscz
*
*/
public class XMLPropertyListConfiguration {
// private static final String TAG = "plist";
/**
* The nested (hierarchical) HashMap which holds our key-value pairs of our
* plist file.
*/
protected HashMap mPlistHashMap;
/**
* Constructor. Parse a plist file from the given InputStream.
*
* @param inputStream
* The InputStream which has the bytes of the plist file we need
* to parse.
*/
public XMLPropertyListConfiguration(InputStream inputStream) {
mPlistHashMap = new HashMap();
if (inputStream != null) {
parse(inputStream);
}
}
/**
* Get an String configuration value for the given key.
*
* @param keyName
* The name of the key to look up in the configuration
* dictionary.
* @return The String value of the specified key.
*/
public String getConfiguration(String keyName) {
return (String) getConfigurationObject(keyName);
}
/**
* Get a String configuration value for the given key. If there is no value
* for the given key, then return the default value.
*
* @param keyName
* The name of the key to look up in the configuration
* dictionary.
* @param defaultValue
* The default value to return if they key has no associated
* value.
* @return The String value of the specified key, or defaultValue if the
* value for keyName is null.
*/
public String getConfigurationWithDefault(String keyName, String defaultValue) {
String value = getConfiguration(keyName);
if (value == null) {
return defaultValue;
}
return value;
}
/**
* Get an Integer configuration value for the given key.
*
* @param keyName
* The name of the key to look up in the configuration
* dictionary.
* @return The Integer value of the specified key.
*/
public Integer getConfigurationInteger(String keyName) {
return (Integer) getConfigurationObject(keyName);
}
/**
* Get an Integer configuration value for the given key. If there is no
* value for the given key, then return the default value.
*
* @param keyName
* The name of the key to look up in the configuration
* dictionary.
* @param defaultValue
* The default value to return if they key has no associated
* value.
* @return The Integer value of the specified key, or defaultValue if the
* value for keyName is null.
*/
public Integer getConfigurationIntegerWithDefault(String keyName, Integer defaultValue) {
Integer value = getConfigurationInteger(keyName);
if (value == null) {
return defaultValue;
}
return value;
}
/**
* Get a Date configuration value for the given key.
*
* @param keyName
* The name of the key to look up in the configuration
* dictionary.
* @return The Date value of the specified key.
*/
public Date getConfigurationDate(String keyName) {
return (Date) getConfigurationObject(keyName);
}
/**
* Get a Date configuration value for the given key. If there is no value
* for the given key, then return the default value.
*
* @param keyName
* The name of the key to look up in the configuration
* dictionary.
* @param defaultValue
* The default value to return if they key has no associated
* value.
* @return The Date value of the specified key, or defaultValue if the value
* for keyName is null.
*/
public Date getConfigurationDateWithDefault(String keyName, Date defaultValue) {
Date value = getConfigurationDate(keyName);
if (value == null) {
return defaultValue;
}
return value;
}
/**
* Get a Boolean configuration value for the given key.
*
* @param keyName
* The name of the key to look up in the configuration
* dictionary.
* @return The Boolean value of the specified key.
*/
public Boolean getConfigurationBoolean(String keyName) {
return (Boolean) getConfigurationObject(keyName);
}
/**
* Get a Boolean configuration value for the given key. If there is no
* value for the given key, then return the default value.
*
* @param keyName
* The name of the key to look up in the configuration
* dictionary.
* @param defaultValue
* The default value to return if they key has no associated
* value.
* @return The Boolean value of the specified key, or defaultValue if the
* value for keyName is null.
*/
public Boolean getConfigurationBooleanWithDefault(String keyName,
Boolean defaultValue) {
Boolean value = getConfigurationBoolean(keyName);
if (value == null) {
return defaultValue;
}
return value;
}
/**
* Utility method which uses a XmlPullParser to iterate through the XML
* elements and build up a hierarchical HashMap representing the key-value
* pairs of the plist configuration file.
*
* @param inputStream
* The InputStream which contains the plist XML file.
*/
public void parse(InputStream inputStream) {
mPlistHashMap.clear();
XmlPullParser parser = Xml.newPullParser();
try {
parser.setInput(inputStream, null);
int eventType = parser.getEventType();
int arrayDepth = 0;
boolean done = false;
boolean parsingArray = false;
String name = null;
String key = null;
Stack> stack = new Stack>();
HashMap dict = null;
ArrayList
Following is a convenience class which extends XMLPropertyListConfiguration to encapsulate the logic of parsing your domain specific plist file. The getter methods are simple delegates to the parent class getConfiguration() methods. Note that you can specify default values to be returned if the key is not present in the plist file.
I have also added some debug methods to print out the keys and values to the debug log.
File : ExamplePListParser.java
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package com.example.plist;
import java.io.InputStream;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Set;
import android.util.Log;
public class ExamplePListParser extends XMLPropertyListConfiguration {
private static final String TAG = "ExamplePListParser";
public ExamplePListParser(InputStream inputStream) {
super(inputStream);
}
public Integer getVersion() {
return getConfigurationIntegerWithDefault("Version", 1);
}
public String getUrl() {
return getConfigurationWithDefault("Url", "http://");
}
public Integer getBrowserVideoWidth(){
return getConfigurationIntegerWithDefault("Browser.VideoWidth", 1280);
}
public Integer getBrowserVideoHeight(){
return getConfigurationIntegerWithDefault("Browser.VideoHeight", 800);
}
public String getRating() {
return getConfigurationWithDefault("Rating", "G");
}
public Date getExpireDate() {
return getConfigurationDateWithDefault("ExpireDate", new Date());
}
public Boolean getHighRes() {
return getConfigurationBooleanWithDefault("HighRes", Boolean.TRUE);
}
/**
* Debug method. Print all the "dict" key names from our plist configuration
* file
*/
public void dumpKeys() {
printHashKeys("root", mPlistHashMap);
}
/**
* Debug method. Iterate through all the methods of this class and print our
* the resulting values.
*/
public void dumpValues() {
try {
Class extends XMLPropertyListConfiguration> c = this.getClass();
Method m[] = c.getDeclaredMethods();
for (int i = 0; i < m.length; i++) {
// only invoke getter methods
if (m[i].getName().startsWith("get")) {
// Log.d(TAG, m[i].getName());
if (m[i].getReturnType() == Integer.class) {
Log.d(TAG, m[i].getName() + " --> " + (Integer) m[i].invoke(this, (Object[]) null));
} else if (m[i].getReturnType() == ArrayList.class) {
Log.d(TAG, m[i].getName() + " --> Array");
dumpArrayList((ArrayList>) m[i].invoke(this, (Object[]) null));
} else if (m[i].getReturnType() == Date.class) {
Log.d(TAG, m[i].getName() + " --> " + (Date) m[i].invoke(this, (Object[]) null));
} else if (m[i].getReturnType() == Boolean.class) {
Log.d(TAG, m[i].getName() + " --> " + (Boolean) m[i].invoke(this, (Object[]) null));
} else if (m[i].getReturnType() == String.class) {
Log.d(TAG, m[i].getName() + " --> " + (String) m[i].invoke(this, (Object[]) null));
} else {
Log.d(TAG, m[i].getName() + " --> UNSUPPORTED TYPE");
}
}
}
} catch (Throwable e) {
e.printStackTrace();
}
}
private void dumpArrayList(ArrayList> list) {
for (Iterator> iter = list.iterator(); iter.hasNext();) {
Object o = iter.next();
if (o instanceof String) {
Log.d(TAG, "\t" + (String) o);
} else if (o instanceof Integer) {
Log.d(TAG, "\t" + (Integer) o);
} else if (o instanceof HashMap) {
Log.d(TAG, "\tHashMap");
@SuppressWarnings("unchecked")
HashMap hash = (HashMap) o;
for (Iterator hashIter = hash.keySet().iterator(); hashIter.hasNext();) {
String key = hashIter.next();
Object value = hash.get(key);
if (value instanceof Integer) {
Log.d(TAG, "\t\t " + key + " = " + (Integer) value);
} else if (value instanceof String) {
Log.d(TAG, "\t\t " + key + " = " + (String) value);
}
}
}
}
}
/**
* Debug method. Iterate through all the keys in the HashMap (dict) and
* print the key names for each child HashMap (dict).
*/
@SuppressWarnings("unchecked")
private void printHashKeys(String key, HashMap map) {
Set keys = map.keySet();
Log.d(TAG, key + " --> " + keys.toString());
for (Iterator iter = keys.iterator(); iter.hasNext();) {
key = iter.next();
Object o = map.get(key);
if (o instanceof HashMap) {
printHashKeys(key, (HashMap) o);
}
}
}
}
Here is a sample plist file.
File : sample.xml
Version
3
Url
http://example.com/video.mp4
ExpireDate
2013-4-20T11:20:00Z
HighRes
Browser
VideoWidth
640
VideoHeight
480
Sample Usage :
ExamplePListParser mPListParser;
InputStream inputStream = new FileInputStream("/sdcard/sample.xml");
if(mPListParser == null) {
mPListParser = new ExamplePListParser(inputStream);
} else {
mPListParser.parse(inputStream);
}
int version = mPListParser.getVersion();
int height = mPListParser.getBrowserVideoHeight();
int width = mPListParser.getBrowserVideoWidth();
String url = mPListParser.getUrl();
String rating = mPListParser.getRating();
Date expireDate = mPListParser.getExpireDate();
boolean highRes = mPListParser.getHighRes();
// debug: print out keys and values
mPListParser.dumpKeys();
mPListParser.dumpValues();