1、XML是什么?
XML是一种可扩展标记语言,其文档结构被设计成树型结构,主要用于数据信息的描述和存储、携带数据和交换数据,通过XML,可以在不兼容的系统之间交换数据。
2、在Android中怎样解析XML文件
优点 | 缺点 | |
DOM | 1.XML树在内存中完整存储,因此可以直接修改其数据结构. 2.可以通过解析器随时访问XML树中的任何一个节点. 3.DOM解析器的API在使用上也相对比较简单. | 如果XML文档体积比较大时,将文档读入内存是非消耗系统资源的 |
SAX | 在读取文档的同时即可对XML进行处理,不必等到文档加载结束,相对快捷。不需要加载进内存,因此不存在占用内存的问题,可以解析超大XML。总结:解析效率高、占存少、灵活性高 | 只能用来读取XML中的数据,无法进行增删改 |
XmlPull | 同SAX(android专有) | 同SAX |
下面将会用实际例子说明3种方式对xml文件的解析,从xml文件中解析出Student对象的集合。
#student.xml
<?xml version="1.0" encoding="utf-8"?>
<school>
<student id='1'>
<name>zhang san</name>
<address>人民南路</address>
</student>
<student id='2'>
<name>li si</name>
<address>体育中心</address>
</student>
<student id='3'>
<name>tao wu</name>
<address>漯河东路</address>
</student>
</school>
对应的Student.java
public class Student {
String id;
String name;
String address;
@Override
public String toString() {
return "student={id:" + id + ",name:" + name + ",address:" + address + "}";
}
}
DOM方式解析xml文件,是与平台和语言无关的方式。基于文档驱动,把dom全部文件读入到内存中,构建一个主流内存的树结构,可以对随机访问和修改节点。
try {
List<Student> lists = new ArrayList<>();
InputStream in = context.getAssets().open("student.xml");
//构造DOM解析器
DocumentBuilder dom = DocumentBuilderFactory.newInstance().newDocumentBuilder();
Document doc = dom.parse(in);
//根据节点名获取student的节点列表
NodeList nodeList = doc.getElementsByTagName("student");
//遍历列表,解析出单个节点
for (int i=0; i < nodeList.getLength(); i++){
Student student = new Student();
Node node = nodeList.item(i);
//获取student节点的id属性值
student.id = node.getAttributes().getNamedItem("id").getNodeValue();
//获取student节点下的子节点列表
NodeList childList = node.getChildNodes();
//遍历子节点
for (int j=0; j<childList.getLength(); j++){
Node child = childList.item(j);
//根据节点名获取内容
if (child.getNodeName().equals("name")){
student.name = child.getTextContent();
}else if (child.getNodeName().equals("address")){
student.address = child.getTextContent();
}
}
//单个student节点解析完,添加到集合
lists.add(student);
}
}catch (Exception e){
e.printStackTrace();
}
XmlPull方式解析xml文件,是android专有,基于流(stream)操作文件,通过获取next()获取事件类型,进而可以获取到标签名和标签的内容。
try {
List<Student> lists = new ArrayList<>();
InputStream in = context.getAssets().open("student.xml");
Reader reader = new InputStreamReader(in);
//构造XmlPull解析器
XmlPullParser xmlPullParser = XmlPullParserFactory.newInstance().newPullParser();
xmlPullParser.setInput(reader);
Student student = null;
//获取事件类型
int eventType = xmlPullParser.getEventType();
//非文档结束类型则执行循环
while(eventType != XmlPullParser.END_DOCUMENT){
//根据事件类型做对应处理
switch (eventType){
case XmlPullParser.START_TAG:
//名为student的开始标签,表示开始解析student结构
if ("student".equals(xmlPullParser.getName())){
student = new Student();
String id = xmlPullParser.getAttributeValue(0);
student.id = id;
}else if ("name".equals(xmlPullParser.getName())){
//名为name的开始标签,直接获取下一个事件的文本,即为name标签间的内容
student.name = xmlPullParser.nextText();
}else if ("address".equals(xmlPullParser.getName())){
//名为address的开始标签,直接获取下一个事件的文本,即为address标签间的内容
student.address = xmlPullParser.nextText();
}
break;
//为结束事件类型,并名为student,表示一个student结构解析完,添加student对象到集合
case XmlPullParser.END_TAG:
if ("student".equals(xmlPullParser.getName())){
lists.add(student);
}
break;
}
//继续获取下一个事件类型
eventType = xmlPullParser.next();
}
} catch (Exception e) {
e.printStackTrace();
}
SAX基于事件驱动,在读取XML文档内容时,事件源顺序地对文档进行扫描,当扫描到文档的开始与结束(Document)标签、节点元素的开始与结束(Element)标签时,直接回调对应的方法。适用于需要处理大型 XML 文档、性能要求较高、不需要对解析文档进行修改且不需要对解析文档多次访问的场合。
try {
InputStream in = context.getAssets().open("student.xml");
//构造SAX解析器
SAXParser sax = SAXParserFactory.newInstance().newSAXParser();
//构造标签处理对象
THandler handler = new THandler();
sax.parse(in, handler);
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
class THandler extends DefaultHandler {
List<Student> list = new ArrayList<>();
Student student = null;
String content = "";
public THandler() {
super();
}
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
super.startElement(uri, localName, qName, attributes);
//开始标签为student,构造student对象并获取id属性
if (qName.equals("student")){
student = new Student();
student.id = attributes.getValue("id");
}
}
@Override
public void endElement(String uri, String localName, String qName) throws SAXException {
super.endElement(uri, localName, qName);
//结束标签为student,表示解析student结构结束,添加对象到集合
if (qName.equals("student")){
list.add(student);
}else if (qName.equals("name")){
student.name = content;
}else if (qName.equals("address")){
student.address = content;
}
content = "";
}
/**
*开始标签和结束标签间的内容
*/
@Override
public void characters(char[] ch, int start, int length) throws SAXException {
super.characters(ch, start, length);
content = new String(ch, start, length);
}
}