您的位置:首页 > 其它

Xml的三种常用解析方法

2016-11-20 19:46 363 查看
一般在开发中,请求到的数据有事会是Json串,但是有时候也会是XML文件类型的数据文本,那么我们怎么对XML类型的数据进行解析呢?

一般我们有三种比较常用的解析方式,DOM解析,SAX解析,和PULL解析。

下面先说一下DOM解析:DOM解析是文档驱动类型,即将整个文档全部读取,然后进行解析,速度相对较慢。

先看要解析的XML文件:

<?xml version="1.0" encoding="UTF-8"?>
李明30李向梅25

下面是解析代码:

public class MainActivity extends Activity {
private ListView listView;
private ArrayList list;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

list = new ArrayList();
listView = (ListView) findViewById(R.id.listView);

}

public void parse(View v) {
// 实例化 DOM解析工厂类:DocumentBuilderFactory。得到解析工厂类对象
DocumentBuilderFactory instance = DocumentBuilderFactory.newInstance();
// 获得解析者对象:DocumentBuilder
try {
DocumentBuilder builder = instance.newDocumentBuilder();
// 解析XML文件,得到文档对象
Document document = builder.parse(getAssets().open("source.xml"));
// 找节点----获取文档元素对象
Element element = document.getDocumentElement();
// 获取person节点,getelementsByTagName:通过标签名字获取节点
NodeList nodeList = element.getElementsByTagName("person");
// 遍历
for (int i = 0; i < nodeList.getLength(); i++) {
Person person = new Person();
// 取出属性node,然后强转成Element元素:等于取出每个元素
Element item = (Element) nodeList.item(i);
String id = item.getAttribute("id");
person.setId(id);
// 取出子节点
NodeList childNodes = item.getChildNodes();
// 遍历
for (int j = 0; j < nodeList.getLength(); j++) {
// 取出每个子节点
Node node = childNodes.item(j);
// 得到节点类型
short nodeType = node.getNodeType();
// 判断是否是元素类型
if (nodeType == node.ELEMENT_NODE) {
// 判断是哪个节点
if (node.getNodeName().equals("name")) {
// 取出文本
String name = node.getFirstChild().getTextContent();
person.setName(name);
} else if (node.getNodeName().equals("age")) {
String age = node.getFirstChild().getTextContent();
person.setAge(age);
}

}
}
list.add(person);

}

listView.setAdapter(new ArrayAdapter(MainActivity.this,
android.R.layout.simple_list_item_1, list));

} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

}

}


第二种是SAX解析:SAX解析是以事件驱动类型的解析方式,速度相对较快

代码如下(分为了两个类,一个是Activity,另一个是类似于帮助类的方法类):

public class MainActivity extends Activity {
private ListView listView;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

listView = (ListView) findViewById(R.id.listView);

}

public void jiexi(View v) {
// 得到sax解析工厂类
SAXParserFactory factory = SAXParserFactory.newInstance();
try {
// 得到具体的解析者
SAXParser parser = factory.newSAXParser();
MyHelper myHelper = new MyHelper();
// 解析
parser.parse(getAssets().open("source.xml"), myHelper);
// 调用MyHelper的方法,得到集合
ArrayList list = myHelper.getList();
// 设置listView适配器
listView.setAdapter(new ArrayAdapter(MainActivity.this,
android.R.layout.simple_list_item_1, list));

} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

}

}


具体的解析任务是放在帮助类里的

public class MyHelper extends DefaultHandler {

private ArrayList list;
private String tag;
private Person person;

//返回集合数据的方法
public ArrayList getList(){
return list;
}

// 开始解析文档时调用
@Override
public void startDocument() throws SAXException {

super.startDocument();
list = new ArrayList();

}

// 结束文档解析时调用
@Override
public void endDocument() throws SAXException {
// TODO Auto-generated method stub
super.endDocument();
}

// 开始解析节点时调用
@Override
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
super.startElement(uri, localName, qName, attributes);

tag = localName;
if (localName.equals("person")) {
person = new Person();
String id = attributes.getValue("id");
person.setId(id);
}
}

// 结束解析节点时调用
@Override
public void endElement(String uri, String localName, String qName)
throws SAXException {
super.endElement(uri, localName, qName);
if (localName.equals("person")) {
list.add(person);
}
}

// 拼接字符串
@Override
public void characters(char[] ch, int start, int length)
throws SAXException {
super.characters(ch, start, length);
String str = new String(ch, start, length);
if (tag.equals("name")) {
person.setName(str);
} else if (tag.equals("age")) {
person.setAge(str);
}

}

}


第三种解析方式PULL解析:

也是以事件驱动为类型的解析方式。

代码如下:

public class MainActivity extends Activity {
private ArrayList list = null;
private Person person = null;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button parse = (Button) findViewById(R.id.parse);
parse.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View v) {
/**
* 1.factory 2.解析者 3.解析
*/
XmlPullParser pullParser = Xml.newPullParser();// 获取解析者
try {
// pullParser.setInput(inputStream--输入流, inputEncoding--输入流的编码);
pullParser.setInput(getAssets().open("source.xml"), "UTF-8");
// 实例化集合
list = new ArrayList();
// 获取事件类型
int eventType = pullParser.getEventType();
// 判断事件类型
// 如果文档没有结束,就要一直解析
while (eventType != XmlPullParser.END_DOCUMENT) {
//
switch (eventType) {
// 判断节点名字
case XmlPullParser.START_TAG:
// 获取节点名字
String startTagName = pullParser.getName();
if (startTagName.equals("person")) {
// 实例化person对象
person = new Person();
// 设置属性
person.setId(pullParser.getAttributeValue(null,"id"));
} else if (startTagName.equals("name")) {
person.setName(pullParser.nextText());
} else if (startTagName.equals("age")) {
person.setAge(pullParser.nextText());
}
break;
case XmlPullParser.END_TAG:
// 获取节点名字
String endTagName = pullParser.getName();
if (endTagName.equals("person")) {
list.add(person);
}
break;
default:
break;
}
// 事件往下移动
eventType = pullParser.next();
}
// 展示
for (int i = 0; i < list.size(); i++) {
System.out.println("zhanghi----->"
+ list.get(i).getName());
}
} catch (XmlPullParserException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
}
}


4000
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: