XML文件解析有四种方式:SAX、DOM、JDOM和DOM4J。
XML文件
<?xml version="1.0" encoding="UTF-8" ?>
<people>
<person personid="E01">
<name>Tony Blair</name>
<address>10 Downing Street,London,UK</address>
<tel>(061) 98765</tel>
<fax>(061) 98765</fax>
<email>blair@enerywhere.com</email>
</person>
<person personid="E02">
<name>Bill Clinton</name>
<address>White House,USA</address>
<tel>(001) 6400 98765</tel>
<fax>(001) 6400 98765</fax>
<email>bill@everywhere.com</email>
</person>
</people>
Person类
public class Person {
private String personid;
private String name;
private String address;
private String tel;
private String fax;
private String email;
public Person() {
}
public Person(String personid, String name, String address, String tel, String fax, String email) {
this.personid = personid;
this.name = name;
this.address = address;
this.tel = tel;
this.fax = fax;
this.email = email;
}
@Override
public String toString() {
return "Person{" +
"personid='" + personid + '\'' +
", name='" + name + '\'' +
", address='" + address + '\'' +
", tel='" + tel + '\'' +
", fax='" + fax + '\'' +
", email='" + email + '\'' +
'}';
}
public String getPersonid() {
return personid;
}
public void setPersonid(String personid) {
this.personid = personid;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getTel() {
return tel;
}
public void setTel(String tel) {
this.tel = tel;
}
public String getFax() {
return fax;
}
public void setFax(String fax) {
this.fax = fax;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
1.SAX方式:
编写数据处理器
public class PersonHandler extends DefaultHandler {
private String tag; //用于记录当前正在解析的标签
private Person person;
private List<Person> ps = new ArrayList<>();
public List<Person> getPersons() {
return ps;
}
@Override
public void startDocument() throws SAXException {
super.startDocument();
System.out.println("解析开始");
}
@Override
public void endDocument() throws SAXException {
super.endDocument();
System.out.println("解析结束");
}
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
super.startElement(uri, localName, qName, attributes);
if ("person".equals(qName)) {
person = new Person();
String personid = attributes.getValue("personid");
person.setPersonid(personid);
}
tag = qName;
}
@Override
public void endElement(String uri, String localName, String qName) throws SAXException {
super.endElement(uri, localName, qName);
if ("person".equals(qName)) {
ps.add(person);
}
tag = null;
}
@Override
public void characters(char[] ch, int start, int length) throws SAXException {
super.characters(ch, start, length);
if (tag != null) {
if ("name".equals(tag)) {
person.setName(new String(ch, start, length));
} else if ("address".equals(tag)) {
person.setAddress(new String(ch, start, length));
} else if ("tel".equals(tag)) {
person.setTel(new String(ch, start, length));
} else if ("fax".equals(tag)) {
person.setFax(new String(ch, start, length));
} else if ("email".equals(tag)) {
person.setEmail(new String(ch, start, length));
}
}
}
}
执行最后SAX解析过程
/**
* SAX解析的特点:
* 1.基于事件驱动
* 2.顺序读取,速度快
* 3.不能任意读取节点(灵活性差)
* 4.解析时占用的内存少
* 5.SAX更适应于在性能要求更高的设备上使用(Android开发中)
*/
public class XMLDemo {
@Test
public void saxParseXML(){
try {
//创建一个SAX解析器工厂对象
SAXParserFactory spf = SAXParserFactory.newInstance();
//通过SAX工厂解析器对象创建一个SAX解析器
SAXParser saxParser = spf.newSAXParser();
//创建一个数据处理器(需要我们自己编写)
PersonHandler ph = new PersonHandler();
//开始解析
InputStream resourceAsStream = Thread.currentThread().getContextClassLoader().getResourceAsStream("com/clayfan/xml/person.xml");
saxParser.parse(resourceAsStream,ph);
List<Person> persons = ph.getPersons();
for (Person person : persons) {
System.out.println(person);
}
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (SAXException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
结果
解析开始
解析结束
Person{personid='E01', name='Tony Blair', address='10 Downing Street,London,UK', tel='(061) 98765', fax='(061) 98765', email='blair@enerywhere.com'}
Person{personid='E02', name='Bill Clinton', address='White House,USA', tel='(001) 6400 98765', fax='(001) 6400 98765', email='bill@everywhere.com'}
2. DOM方式
/** * DOM解析XML * 1.基于树型结构,通过解析器一次性把文档加载到内存中,所以会比较占用内存,可以随机访问 * 更加灵活,更适合在WEB开发中使用 * @throws ParserConfigurationException * @throws IOException * @throws SAXException */ @Test public void domParseXML() throws ParserConfigurationException, IOException, SAXException { //创建一个DOM解析器工厂对象 DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance(); //通过工厂对象创建解析器对象 DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder(); //解析文档 InputStream resourceAsStream = Thread.currentThread().getContextClassLoader().getResourceAsStream("com/clayfan/xml/person.xml"); Document document = documentBuilder.parse(resourceAsStream); //从内存中读取数据 NodeList persons = document.getElementsByTagName("person"); Person p = null; ArrayList<Person> people = new ArrayList<>(); for (int i = 0; i < persons.getLength(); i++) { Node item = persons.item(i); //获取节点的属性值 String personid = item.getAttributes().getNamedItem("personid").getNodeName(); p = new Person(); p.setPersonid(personid); //获取当前节点的所有子节点 NodeList childNodes = item.getChildNodes(); for (int j = 0; j < childNodes.getLength(); j++) { Node item1 = childNodes.item(j); String nodeName = item1.getNodeName(); if ("name".equals(nodeName)) { p.setName(item1.getFirstChild().getNodeValue()); }else if("address".equals(nodeName)){ p.setAddress(item1.getFirstChild().getNodeValue()); }else if("tel".equals(nodeName)){ p.setTel(item1.getFirstChild().getNodeValue()); }else if("fax".equals(nodeName)){ p.setFax(item1.getFirstChild().getNodeValue()); }else if("email".equals(nodeName)){ p.setEmail(item1.getFirstChild().getNodeValue()); } } people.add(p); } for(Person pp:people){ System.out.println(pp); } }
3.JDOM方式:
下载地址:http://www.jdom.org/downloads/index.html
/** * JDOM解析XML * 1.与DOM类似基于树型结构 * 2.与DOM的区别 * 第三方开源的组件 * 实现使用JAVA的Collection接口 * 效率比DOM更快 * @throws JDOMException * @throws IOException */ @Test public void jdomParseXML() throws JDOMException, IOException { SAXBuilder saxBuilder = new SAXBuilder(); InputStream resourceAsStream = Thread.currentThread().getContextClassLoader().getResourceAsStream("com/clayfan/xml/person.xml"); org.jdom2.Document build = saxBuilder.build(resourceAsStream); Element rootElement = build.getRootElement(); List<Person> list = new ArrayList<>(); Person person = null; List<Element> children = rootElement.getChildren(); for(Element element:children){ person= new Person(); String personid = element.getAttributeValue("personid"); person.setPersonid(personid); List<Element> children1 = element.getChildren(); for(Element e:children1){ String tag = e.getName(); if ("name".equals(tag)) { person.setName(e.getText()); }else if("address".equals(tag)){ person.setAddress(e.getText()); }else if("tel".equals(tag)){ person.setTel(e.getText()); }else if("fax".equals(tag)){ person.setFax(e.getText()); }else if("email".equals(tag)){ person.setEmail(e.getText()); } } list.add(person); } for(Person pp:list){ System.out.println(pp); } }
4.DOM4J方式:
/** * DOM4J解析XML * 基于树型结构,第三方组件 * 解析速度快,效率更高,使用的JAVA中的迭代器实现数据读取,在WEB框架中使用较多(Hibernate) * * @throws DocumentException */ @Test public void dom4jParseXML() throws DocumentException { SAXReader reader = new SAXReader(); InputStream resourceAsStream = Thread.currentThread().getContextClassLoader().getResourceAsStream("com/clayfan/xml/person.xml"); org.dom4j.Document read = reader.read(resourceAsStream); org.dom4j.Element rootElement = read.getRootElement(); Iterator<org.dom4j.Element> iterator = rootElement.elementIterator(); ArrayList<Person> persons = new ArrayList<>(); Person person = null; while(iterator.hasNext()){ person = new Person(); org.dom4j.Element element = iterator.next(); person.setPersonid(element.attributeValue("personid")); Iterator<org.dom4j.Element> iterator1 = element.elementIterator(); while(iterator1.hasNext()){ org.dom4j.Element next = iterator1.next(); String tag = next.getName(); if ("name".equals(tag)) { person.setName(next.getText()); }else if("address".equals(tag)){ person.setAddress(next.getText()); }else if("tel".equals(tag)){ person.setTel(next.getText()); }else if("fax".equals(tag)){ person.setFax(next.getText()); }else if("email".equals(tag)){ person.setEmail(next.getText()); } } persons.add(person); } for(Person pp:persons){ System.out.println(pp); } }