您的位置:首页 > 移动开发 > Android开发

Java/android中解析xml的3种方法

2016-07-05 21:20 423 查看
XML现在已经成为一种通用的数据交换格式,它的平台无关性,语言无关性,系统无关性,给数据集成与交互带来了极大的方便。对于XML本身的语法知识与技术细节,需要阅读相关的技术文献,这里面包括的内容有DOM(Document Object Model),DTD(Document Type Definition),SAX(Simple API for XML),XSD(Xml Schema
Definition),XSLT(Extensible Stylesheet Language Transformations),具体可参阅w3c官方网站文档http://www.w3.org获取更多信息。

XML在不同的语言里解析方式都是一样的,只不过实现的语法不同而已。基本的解析方式有两种,一种叫SAX,另一种叫DOM。SAX是基于事件流的解析,DOM是基于XML文档树结构的解析。

3种解析XML方法的比较



一、DOM解析XML数据



核心代码:

DomHelper.java

public class DomHelper {
public static ArrayList<Person> queryXML(Context context)
{
ArrayList<Person> Persons = new ArrayList<Person>();
try {
//①获得DOM解析器的工厂示例:
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
//②从Dom工厂中获得dom解析器
DocumentBuilder dbBuilder = dbFactory.newDocumentBuilder();
//③把要解析的xml文件读入Dom解析器
Document doc = dbBuilder.parse(context.getAssets().open("person2.xml"));
System.out.println("处理该文档的DomImplemention对象=" + doc.getImplementation());
//④得到文档中名称为person的元素的结点列表
NodeList nList = doc.getElementsByTagName("person");
//⑤遍历该集合,显示集合中的元素以及子元素的名字
for(int i = 0;i < nList.getLength();i++)
{
//先从Person元素开始解析
Element personElement = (Element) nList.item(i);
Person p = new Person();
p.setId(Integer.valueOf(personElement.getAttribute("id")));

//获取person下的name和age的Note集合
NodeList childNoList = personElement.getChildNodes();
for(int j = 0;j < childNoList.getLength();j++)
{
Node childNode = childNoList.item(j);
//判断子note类型是否为元素Note
if(childNode.getNodeType() == Node.ELEMENT_NODE)
{
Element childElement = (Element) childNode;
if("name".equals(childElement.getNodeName()))
p.setName(childElement.getFirstChild().getNodeValue());
else if("age".equals(childElement.getNodeName()))
p.setAge(Integer.valueOf(childElement.getFirstChild().getNodeValue()));
}
}
Persons.add(p);
}
} catch (Exception e) {e.printStackTrace();}
return Persons;
}
}

代码分析:

从代码我们就可以看出DOM解析XML的流程,先整个文件读入Dom解析器,然后形成一棵树, 然后我们可以遍历节点列表获取我们需要的数据!

为解决DOM的问题,出现了SAX。

二、SAX解析XML数据



核心代码:

SAX解析类:SaxHelper.java:

public class SaxHelper extends DefaultHandler {
private Person person;
private ArrayList<Person> persons;
//当前解析的元素标签
private String tagName = null;

/**
* 当读取到文档开始标志是触发,通常在这里完成一些初始化操作
*/
@Override
public void startDocument() throws SAXException {
this.persons = new ArrayList<Person>();
Log.i("SAX", "读取到文档头,开始解析xml");
}

/**
* 读到一个开始标签时调用,第二个参数为标签名,最后一个参数为属性数组
*/
@Override
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
if (localName.equals("person")) {
person = new Person();
person.setId(Integer.parseInt(attributes.getValue("id")));
Log.i("SAX", "开始处理person元素~");
}
this.tagName = localName;
}

/**
* 读到到内容,第一个参数为字符串内容,后面依次为起始位置与长度
*/

@Override
public void characters(char[] ch, int start, int length)
throws SAXException {
//判断当前标签是否有效
if (this.tagName != null) {
String data = new String(ch, start, length);
//读取标签中的内容
if (this.tagName.equals("name")) {
this.person.setName(data);
Log.i("SAX", "处理name元素内容");
} else if (this.tagName.equals("age")) {
this.person.setAge(Integer.parseInt(data));
Log.i("SAX", "处理age元素内容");
}

}

}

/**
* 处理元素结束时触发,这里将对象添加到结合中
*/
@Override
public void endElement(String uri, String localName, String qName)
throws SAXException {
if (localName.equals("person")) {
this.persons.add(person);
person = null;
Log.i("SAX", "处理person元素结束~");
}
this.tagName = null;
}

/**
* 读取到文档结尾时触发,
*/
@Override
public void endDocument() throws SAXException {
super.endDocument();
Log.i("SAX", "读取到文档尾,xml解析结束");
}

//获取persons集合
public ArrayList<Person> getPersons() {
return persons;
}

}

然后我们在MainActivity.java中写上写上这样一个方法,然后要解析XML的时候调用下 就好了~

private ArrayList<Person> readxmlForSAX() throws Exception {
//获取文件资源建立输入流对象
InputStream is = getAssets().open("person1.xml");
//①创建XML解析处理器
SaxHelper ss = new SaxHelper();
//②得到SAX解析工厂
SAXParserFactory factory = SAXParserFactory.newInstance();
//③创建SAX解析器
SAXParser parser = factory.newSAXParser();
//④将xml解析处理器分配给解析器,对文档进行解析,将事件发送给处理器
parser.parse(is, ss);
is.close();
return ss.getPersons();
}

person1.xml

<?xml version="1.0" encoding="UTF-8"?>
<persons>
<person id = "11">
<name>SAX解析</name>
<age>18</age>
</person>
<person id = "13">
<name>XML1</name>
<age>43</age>
</person>
</persons>

结果



三、PULL解析XML数据(Andorid)



使用PULL解析XML数据的流程:



核心代码:

public static ArrayList<Person> getPersons(InputStream xml)throws Exception
{
//XmlPullParserFactory pullPaser = XmlPullParserFactory.newInstance();
ArrayList<Person> persons = null;
Person person = null;
// 创建一个xml解析的工厂
XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
// 获得xml解析类的引用
XmlPullParser parser = factory.newPullParser();
parser.setInput(xml, "UTF-8");
// 获得事件的类型
int eventType = parser.getEventType();
while (eventType != XmlPullParser.END_DOCUMENT) {
switch (eventType) {
case XmlPullParser.START_DOCUMENT:
persons = new ArrayList<Person>();
break;
case XmlPullParser.START_TAG:
if ("person".equals(parser.getName())) {
person = new Person();
// 取出属性值
int id = Integer.parseInt(parser.getAttributeValue(0));
person.setId(id);
} else if ("name".equals(parser.getName())) {
String name = parser.nextText();// 获取该节点的内容
person.setName(name);
} else if ("age".equals(parser.getName())) {
int age = Integer.parseInt(parser.nextText());
person.setAge(age);
}
break;
case XmlPullParser.END_TAG:
if ("person".equals(parser.getName())) {
persons.add(person);
person = null;
}
break;
}
eventType = parser.next();
}
return persons;
}

使用Pull生成xml数据的流程:



核心代码:

public static void save(List<Person> persons, OutputStream out) throws Exception {
XmlSerializer serializer = Xml.newSerializer();
serializer.setOutput(out, "UTF-8");
serializer.startDocument("UTF-8", true);
serializer.startTag(null, "persons");
for (Person p : persons) {
serializer.startTag(null, "person");
serializer.attribute(null, "id", p.getId() + "");
serializer.startTag(null, "name");
serializer.text(p.getName());
serializer.endTag(null, "name");
serializer.startTag(null, "age");
serializer.text(p.getAge() + "");
serializer.endTag(null, "age");
serializer.endTag(null, "person");
}

serializer.endTag(null, "persons");
serializer.endDocument();
out.flush();
out.close();
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  dom java xml