XML解析

来源:互联网 发布:极客学院 java 编辑:程序博客网 时间:2024/06/07 15:23

XML的用途

1、充当显示数据

2、存储数据的功能

3.以XML描述数据,并在联系服务器与系统的其余部分之间传递

从某种角度讲,XML是数据的封装和消息的传递技术

SAX解析XML

SAX是读取和操作XML数据更快捷更轻量的方法,SAX允许你在读取文档时处理它,从而不必等待整个文档被存储之后才采取操作,他不涉及DOM所必需的开销和概念跳跃。SAX API是一个基于事件的API,适用于处理数据流,即随着数据的流动而依次处理数据,SAX API在其解析您的文档时发生一定事件的时候会通知您,在您对其响应时,您不做保存的数据将会被抛弃

SAX API中主要有四种处理事件的接口,他们分别是ContentHandler,DTDandler,EntityResolver,ErrorHandler,实际上只要继承defaultHandler类就可以,DefaultHandler实现了这四个事件处理器接口,然后提供了每个抽象方法的默认实现。

XMLDemo,java

public class XMLDemo {@Testpublic void saxParseXML() throws ParserConfigurationException, SAXException, IOException{//1创建一个SAX解析器工厂对象SAXParserFactory saxParserFactory=SAXParserFactory.newInstance();//2通过工厂对象创建SAX解析器SAXParser saxParser=saxParserFactory.newSAXParser();//3创建一个数据处理器,需要我们自己来写PersonHandler personHandler=new PersonHandler();//4开始解析InputStream is=Thread.currentThread().getContextClassLoader().getResourceAsStream("person.xml");//当前线程的类加载器saxParser.parse(is,personHandler);List<Person> persons=personHandler.getPersons();for(Person p:persons){System.out.println(p);}}}
Person.java

public class Person {private String personid;private String name;private String address;private String tel;private String fax;private String email;@Overridepublic 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;}}
PersonHandler.java

import org.xml.sax.SAXException;import org.xml.sax.helpers.DefaultHandler;//SAX解析的特点//基于事件驱动,顺序读取,速度快,不能任意读取节点,解析时占用的内存小,SAX更适用于在性能要求更高的设备上使用public class PersonHandler extends DefaultHandler{private List<Person> persons=null;private Person p;//Dang前解析的对象private String tag;//用于记录当前正则解析的标签名public List<Person> getPersons(){return persons;}public void startDocument()throws SAXException{//开始解析文档时调用super.startDocument();persons=new ArrayList<>();System.out.println("开始解析文档....");}public void endDoucment() throws SAXException{super.endDocument();//文件解析结束时调用System.out.println("解析文档结束了");}//解析开始元素时调用public void startElement(String uri,String localName,String qName,org.xml.sax.Attributes attributes)throws SAXException{super.startElement(uri, localName, qName, attributes);if("person".equals(qName)){p=new Person();String personid=attributes.getValue("personid");p.setPersonid(personid);}tag=qName;System.out.println("endElement"+qName);}//解析元素结束时调用,参数分别是命名空间,不带前缀的标签名,带前缀的标签名(aa:person),当前标签的属性集合,public void endElement(String uri,String localName,String qName)throws SAXException{super.endElement(uri, localName, qName);if("person".equals(qName)){persons.add(p);}tag=null;}//解xi文本内容时调用public void characters(char[] ch,int start,int length)throws SAXException{super.characters(ch, start, length);if(tag!=null){if("name".equals(tag)){p.setName(new String(ch, start, length));}else if("address".equals(tag)){p.setAddress(new String(ch, start, length));}else if("tel".equals(tag)){p.setTel(new String(ch, start, length));}else if("fax".equals(tag)){p.setFax(new String(ch, start, length));}else if("email".equals(tag)){p.setEmail(new String(ch, start, length));}System.out.println(ch);}}}
person.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>1839550062@qq.com</email></person><person personid="E02"><name>xiaoyu</name><address>white house</address><tel>(001)6400 98765</tel><fax>(001)6400 98765</fax><email>3520203238@qq.com</email></person></people>

下面是DOM解析XML的代码:

@Test//DOM解析XML//基于树形结构,通过解析器一次性把文档加载到内容中,所以比较占内存,但是随即访问更灵活。更适合在WEB开发中使用public void domParseXML() throws SAXException, IOException, ParserConfigurationException{//创建一个DOM解析器工厂对象DocumentBuilderFactory factory=DocumentBuilderFactory.newInstance();//通过工厂对象创建解析器对象DocumentBuilder documentBuilder=factory.newDocumentBuilder();//解析文档InputStream is=Thread.currentThread().getContextClassLoader().getResourceAsStream("person.xml");//发代码完成后,整个xml文档已经被加载到内存中,以树状形式存储Document doc= documentBuilder.parse(is);//从内存中读取数据//获取节点名称为person的所有节点,返回节点集合NodeList personNodeList=doc.getElementsByTagName("person");ArrayList<Person>persons=new ArrayList<>();Person p=null;//此循环迭代两次,查找<person>for(int i=0;i<personNodeList.getLength();i++){Node personNode=personNodeList.item(i);p=new Person();//获取节点的属性值String personid=personNode.getAttributes().getNamedItem("personid").getNodeValue();p.setPersonid(personid);NodeList childNodes=personNode.getChildNodes();for(int j=0;j<childNodes.getLength();j++){//循环5次查找子节点<name>之类的Node item=childNodes.item(j);String nodeName=item.getNodeName();if("name".equals(nodeName)){p.setName(item.getFirstChild().getNodeValue());}else if("address".equals(nodeName)){p.setAddress(item.getFirstChild().getNodeValue());}else if("tel".equals(nodeName)){p.setTel(item.getFirstChild().getNodeValue());}else if("fax".equals(nodeName)){p.setFax(item.getFirstChild().getNodeValue());}else if("email".equals(nodeName)){p.setEmail(item.getFirstChild().getNodeValue());}}persons.add(p);}System.out.println("结果");System.out.println(Arrays.toString(persons.toArray()));}

https://dom4j.github.io/网址下载dom4j.jar包,引入到工程中。

dom4j是一个非常非常优秀的Java XML API,具有性能优异,功能强大和极端易用使用的特点,同时他是一个开发源代码的软件,可以在SourceForge上找到他,在对主流的Java XML API进行的性能、功能和易用性的测评,dom4j无论在哪个方面都是非常出色的,如今你可以看到越来越多的Java软件都在使用dom4j来读写XML,特别值得一提的是连Sun的JAXM也在使用dom4j,这是必须使用的Jar包,Hibernate用它来读写配置文件。

JDOM和DOM在性能测试时表现不佳,在测10M文档时内存溢出

SAX表现较好,这要依赖于他特定的解析方式,一个SAX检测即将到来的XML流,但并没有载入到内存。

DOM4J是这场测试的获胜者,目前许多开源项目中大量采用DOM4J。

DOM4J的测试方法:

@Test/** * 基于树形结构,第三方组件 * 解析速度快,效率高,使用的java中的迭代器,在WEB框架中使用较多 * @throws DocumentException */public void dom4jParseXML() throws DocumentException{//创建DOM4j的解析器对象SAXReader reader=new SAXReader();InputStream is=Thread.currentThread().getContextClassLoader().getResourceAsStream("person.xml");//类加载器Document doc=reader.read(is);Element rootElement=doc.getRootElement();Iterator<Element> iterator=rootElement.elementIterator();ArrayList<Person> persons=new ArrayList<>();Person p=null;while(iterator.hasNext()){p=new Person();Element e=iterator.next();p.setPersonid(e.attributeValue("personid"));Iterator iterator1=e.elementIterator();while(iterator1.hasNext()){Element next=(Element) iterator1.next();String tag=next.getName();if("name".equals(tag)){p.setName(next.getText());}else if("address".equals(tag)){p.setName(next.getText());}else if("tel".equals(tag)){p.setName(next.getText());}else if("fax".equals(tag)){p.setName(next.getText());}else if("email".equals(tag)){p.setName(next.getText());}}persons.add(p);}System.out.println("结果:");System.out.println(Arrays.toString(persons.toArray()));}








原创粉丝点击