1.XmlPullParser
-
优点:读取方便、内存损耗小
-
缺点:需要知道节点名称(使用泛型优化)
原理:
基于事件驱动,根据XmlPullParser返回不同的标签进行获取xml数据。
int type = xmlPullParser.getEventType();
while (type!= XmlPullParser.END_DOCUMENT) {
switch (type) {
case XmlPullParser.START_DOCUMENT:
break;
case XmlPullParser.START_TAG:
break;
case XmlPullParser.END_TAG:
break;
case XmlPullParser.END_DOCUMENT:
break;
}
type = xmlPullParser.next();
}
具体例子:
主要是获取到xml的属性赋值给clazz对象, 通过xmlPullParser.nextText()获取value,通过xmlPullParser.getName();获取key进行赋值
public static <T> List<T> xmlToObject(InputStream xml , Class<T> clazz , String tagEntity){
List<T> list = null;
try{
XmlPullParser xmlPullParser = Xml.newPullParser();
xmlPullParser.setInput(xml,"UTF-8");
Field[] fields = clazz.getDeclaredFields();
int type = xmlPullParser.getEventType();
String lastTag = "";
T t = null;
while (type!= XmlPullParser.END_DOCUMENT) {
switch (type) {
case XmlPullParser.START_DOCUMENT:
String START_DOCUMENTtagName = xmlPullParser.getName();
list = new ArrayList<T>();
break;
case XmlPullParser.START_TAG:
String tagName = xmlPullParser.getName();
if (tagEntity.equals(tagName)) {
t = clazz.newInstance();
lastTag = tagEntity;
} else if (tagEntity.equals(lastTag)) {
String value = xmlPullParser.nextText();
String filedName = xmlPullParser.getName();
for (Field field : fields) {
setFieldValue(t, field, filedName, value);
}
}
break;
case XmlPullParser.END_TAG:
tagName = xmlPullParser.getName();
if (tagEntity.equals(tagName)) {
list.add(t);
lastTag = "";
}
break;
case XmlPullParser.END_DOCUMENT:
String tagName1 = xmlPullParser.getName();
break;
}
type = xmlPullParser.next();
}
}catch (Exception e){
e.printStackTrace();
}
return list;
}
public static <T> void setFieldValue (T t, Field field , String fieldName ,String value){
String name =field.getName();
if(!fieldName.equals(name)){
return;
}
//get type
Type type =field.getType();
//get modifie
int typeCode =field.getModifiers();
String typeName =type.toString();
try{
switch (typeName){
case "class java.lang.String":
if(Modifier.isPublic(typeCode)){
field.set(t,value);
}else{
Method method =t.getClass().getMethod("set" + getMethodName(fieldName),String.class);
method.invoke(t,value);
}
break;
case "double":
if(Modifier.isPublic(typeCode)){
field.set(t,Double.valueOf(value) );
}else{
Method method =t.getClass().getMethod("set" + getMethodName(fieldName),double.class);
method.invoke(t,Double.valueOf(value) );
}
break;
case "int":
if(Modifier.isPublic(typeCode)){
field.set(t,Integer.valueOf(value) );
}else{
Method method =t.getClass().getMethod("set" + getMethodName(fieldName),int.class);
method.invoke(t,Integer.valueOf(value) );
}
break;
case "float":
if(Modifier.isPublic(typeCode)){
field.set(t,Float.valueOf(value) );
}else{
Method method =t.getClass().getMethod("set" + getMethodName(fieldName),float.class);
method.invoke(t,Float.valueOf(value) );
}
break;
}
}catch (Exception e){
e.printStackTrace();
}
}
private static String getMethodName(String fieldName) throws Exception{
byte[] items = fieldName.getBytes();
items[0] = (byte) ((char)items[0] - 'a' + 'A');
return new String(items);
}
2.Sax
-
优点:内存占用少。
-
缺点:无法修改xml内容,每次都要按顺序读取。
原理:基于事件驱动,扫描文件的开始和结束,继承DefaultHandler类在对应的方法进行处理
例子:
public class SaxHelper<T> extends DefaultHandler {
String TAG = SaxHelper.class.getSimpleName();
public T t;
private ArrayList<T> tArrayList;
private String tagName= null;
Class<T> clazz;
Field[] fields;
public SaxHelper(Class<T> mClazz){
clazz=mClazz;
fields = clazz.getDeclaredFields();
}
@Override
public void startDocument() throws SAXException {
super.startDocument();
this.tArrayList = new ArrayList<T>();
}
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
super.startElement(uri, localName, qName, attributes);
if(localName.equals(clazz.getSimpleName().toLowerCase())){
try {
this.t = clazz.newInstance();
fields = clazz.getDeclaredFields();
for (Field field : fields) {
if(field.getName().equals(Contants.attributeName)){
ReflectUtil.setFieldValue(this.t, field, Contants.attributeName, attributes.getValue(Contants.attributeName));
}
}
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
}catch (Exception e){
e.printStackTrace();
}
}
this.tagName = localName;
}
@Override
public void characters(char[] ch, int start, int length) throws SAXException {
super.characters(ch, start, length);
try {
if(this.tagName != null) {
String data = new String(ch,start, length);
if(data!=null){
for (Field field : fields) {
if(this.tagName.equals(field.getName())){
ReflectUtil.setFieldValue(this.t, field, field.getName(), data);
}
}
}
}
}catch (Exception e){
e.printStackTrace();
}
}
@Override
public void endElement(String uri, String localName, String qName) throws SAXException {
super.endElement(uri, localName, qName);
if(localName.equals(clazz.getSimpleName().toLowerCase())){
this.tArrayList.add(t);
t=null;
}
this.tagName = null;
}
@Override
public void endDocument() throws SAXException {
super.endDocument();
Log.i("SAX", "endDocument");
}
//获取persons集合
public ArrayList<T> getXmlArrayList() {
return this.tArrayList;
}
}
3.Dom
-
优点:检索修改效率高
-
缺点:损耗内存大,每次都会把xml全部扫描
原理:文档驱动,整个文档树保存在内存中,以便进行操作。
例子:
public class DomHelper {
static String TAG = DomHelper.class.getSimpleName();
public static <T>ArrayList<T> queryXML(Context context,Class<T> clazz){
ArrayList<T> tArrayList = new ArrayList<T>();
try{
DocumentBuilderFactory dbFactory= DocumentBuilderFactory.newInstance();
DocumentBuilder dbBuilder = dbFactory.newDocumentBuilder();
Document doc = dbBuilder.parse(context.getAssets().open("person3.xml"));
NodeList nodeList = doc.getElementsByTagName(clazz.getSimpleName().toLowerCase());
for(int i = 0;i < nodeList.getLength();i++){
Element mElement =(Element)nodeList.item(i);
T t = clazz.newInstance();
//set attribute
Field field = clazz.getDeclaredField(Contants.attributeName);
ReflectUtil.setFieldValue(t, field, Contants.attributeName, mElement.getAttribute(Contants.attributeName));
//set childNoList
NodeList childNoList = mElement.getChildNodes();
for(int j = 0;j<childNoList.getLength();j++){
Node childNode = childNoList.item(j);
if(childNode.getNodeType() == Node.ELEMENT_NODE){
Element childElement = (Element)childNode;
Field[] childField = clazz.getDeclaredFields();
for (Field mfield:childField){ if(childElement.getNodeName().equals(mfield.getName())){
ReflectUtil.setFieldValue(t, mfield, mfield.getName(), childElement.getFirstChild().getNodeValue());
}
}
}
}
tArrayList.add(t);
}
}catch (Exception e){
e.printStackTrace();
}
return tArrayList;
}
}