Skip to content

Instantly share code, notes, and snippets.

@amlcurran
Created February 19, 2013 13:51
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save amlcurran/4986074 to your computer and use it in GitHub Desktop.
Save amlcurran/4986074 to your computer and use it in GitHub Desktop.
Helper class that can generate an List of a given class from a simple XML file.
/* Copyright 2013 Alex Curran
Licensed 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.espian.formulae.lib;
import android.content.Context;
import android.util.Log;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlPullParserFactory;
import java.io.IOException;
import java.io.InputStreamReader;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
/**
* Helper class that can generate an {@link List} from a simple XML file. This class
* is abstract and must be overriden. XmlFileParser will read the XML file supplied and
* attempt to set any <strong>public</strong> fields where the field name matches the XML
* tag. Fields must be public, but XmlFileParser is not case sensitive (so a XML tag of
* <em>degreeofrotation</em> will match the field <em>degreeOfRotation</em>. Subsequent versions will
* include a way of using setting fields if avaiable.
* @param <T> The object which to return a list of
*/
public abstract class XmlFileParser<T extends Object> {
private T internal;
public XmlFileParser() {
internal = createBlankClass();
}
public List<T> readFile(int resourceId, Context c) {
return readFile(new InputStreamReader(c.getResources().openRawResource(resourceId)), null);
}
public List<T> readFile(int resourceId, Context c, String enclosingTag) {
return readFile(new InputStreamReader(c.getResources().openRawResource(resourceId)), enclosingTag);
}
public List<T> readFile(InputStreamReader isr, String enclosingTag) {
try {
XmlPullParserFactory xppf = XmlPullParserFactory.newInstance();
XmlPullParser xpp = xppf.newPullParser();
xpp.setInput(isr);
ArrayList<T> list = new ArrayList<T>();
Field target = null;
Method set = null;
T current = null;
if (enclosingTag == null)
enclosingTag = current.getClass().getSimpleName();
int event = xpp.getEventType();
while (event != XmlPullParser.END_DOCUMENT) {
switch (event) {
case XmlPullParser.START_TAG:
String tag = xpp.getName();
if (tag.toLowerCase().equals(enclosingTag.toLowerCase())) {
current = createBlankClass();
target = null;
} else if (!tag.equals("xml")) {
try {
target = internal.getClass().getField(tag);
} catch (NoSuchFieldException nsfe) {
Log.e("XmlFileParser:" + internal.getClass().getSimpleName(), "Class has no " +
"field matching tag " + tag);
target = null;
}
}
break;
case XmlPullParser.TEXT:
if (target != null && !xpp.isWhitespace() && current != null) {
Object modified = parseValue(target.getName(), xpp.getText());
target.set(current, modified);
}
break;
case XmlPullParser.END_TAG:
String endTag = xpp.getName();
if (endTag.toLowerCase().equals(enclosingTag.toLowerCase())) {
list.add(current);
current = null;
target = null;
}
break;
}
event = xpp.next();
}
return list;
} catch (XmlPullParserException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return null;
}
public Object parseValue(String tag, String text) {
return text;
}
public abstract T createBlankClass();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment