解析xml文档总结(一)

来源:互联网 发布:阿迪达斯淘宝推荐店铺 编辑:程序博客网 时间:2024/05/19 17:52

开发javaWEB项目,经常都要遇到xml文件,我们只要在xml配置项目的一些属性,那么项目就可以按我们所想的运作了。那么xml文件的数据是如何转化为系统可以识别的信息呢?这就需要解析xml文件了。

要解析xml文件就要有xml解析器,比较著名的有Apache的Xerces,微软的MSXML,Oracle的XMLParser等。如果系统要更换解析器就要修改源代码,那也太不人道了。幸运的事,这些解析器大都支持两套API:DOM和SAX,因此,我们针对DOM接口或SAX接口编程可以极大简化更改解析器时代码的修改。

另外,Oracle制定的JAXP规范在解析器之上提供了一层抽象,使我们可以独立于厂商API进行编程。在JavaSE中,JAXP的开发包由javax.xml,org.w3c.dom和org.xml.sax三个包组成。其中javax.xml.parsers包中定义了几个工厂方法用于加载DOM或SAX的实现类。其实现类可以很方便地更换,只要修改制定文件的一些配置即可。这个后面细讲。

因此针对JAXP编程可以随意更换解析器而不用修改任何的源代码。

以下具体说说DOM和SAX。

先说DOM吧。DOM把xml文档处理成一棵节点树,xml的元素,属性,文本,注释,数据段等在DOM中都有对应的类。且看类图:


有了这张图,再看后面的代码应该能容易一些。给出一个例子吧:

books.xml内容如下:

<?xml version="1.0" encoding="utf-8"?><books><book name="java"><author>Bruce</author><price>100</price></book><book name="c++"><author>Dinail</author><price>80</price></book></books>

代码如下:

import java.io.File;import java.io.IOException;import javax.xml.parsers.DocumentBuilder;import javax.xml.parsers.DocumentBuilderFactory;import javax.xml.parsers.ParserConfigurationException;import org.w3c.dom.Document;import org.w3c.dom.Element;import org.w3c.dom.Node;import org.w3c.dom.NodeList;import org.xml.sax.SAXException;public class SimpleTest {public void test(){DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();//获得解析器实现类,获取方法后面讲try {DocumentBuilder db = dbf.newDocumentBuilder();Document d = db.parse(new File("books.xml"));NodeList nl = d.getElementsByTagName("book");//获得所有的book节点for(int i = 0;i < nl.getLength();i++){Element e = (Element)nl.item(i);//将book节点转换成元素String bookname = nl.item(i).getAttributes().item(0).getNodeValue();//获得book节点的属性列表,然后是第一个属性并得到其值Node n1 = e.getElementsByTagName("author").item(0);Node n2 = e.getElementsByTagName("price").item(0);String author = n1.getFirstChild().getNodeValue();String price = n2.getLastChild().getNodeValue();System.out.println("bookname:"+bookname+"\n\tauthor:"+author+"\n\tprice:"+price);}} catch (ParserConfigurationException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (SAXException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}public static void main(String[] args) {new SimpleTest().test();}}

应该注意的是,<book>与<author>之间有一个text节点,类似的,还有其他一些空白节点。其他的注释已经讲的清楚了,以下是输出:

bookname:javaauthor:Bruceprice:100bookname:c++author:Dinailprice:80

ok,回到上面的一个问题,如果要换解析器怎么办呢?或者说DocumentBuilderFactory.newInstance()是怎么找到实现类的呢?且听我细细道来。

关键之处在于javax.xml.parsers.DocumentBuilderFactory这个系统属性的设置。

可以通过System.setProperty("javax.xml.parsers.DocumentBuilderFactory","org.apache.parsers.jaxp.DocumentBuilderFactoryImp")

可以在执行时指定:java -Djavax.xml.parsers.DocumentBuilderFactory=org.apache.parsers.jaxp.DocumentBuilderFactoryImp

可以在jre/lib下添加jaxp.properties文件并添加一条记录:javax.xml.parsers.DocumentBuilderFactory=org.apache.parsers.jaxp.DocumentBuilderFactoryImp

如果都没找到,那就使用JDK自带的解析器了,在com\sun\org\apache\xerces\internal下


以下是SAX解析xml的一个例子,xml文件用上面那个:

import java.io.File;import java.io.IOException;import javax.xml.parsers.ParserConfigurationException;import javax.xml.parsers.SAXParser;import javax.xml.parsers.SAXParserFactory;import org.xml.sax.Attributes;import org.xml.sax.SAXException;import org.xml.sax.helpers.DefaultHandler;public class SimpleTest {public void test(){SAXParserFactory spf = SAXParserFactory.newInstance();try {SAXParser sp = spf.newSAXParser();sp.parse(new File("books.xml"),new SAXHandler());} catch (ParserConfigurationException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (SAXException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}public static void main(String[] args) {// TODO Auto-generated method stubnew SimpleTest().test();}}class SAXHandler extends DefaultHandler{@Overridepublic void startDocument() throws SAXException{System.out.println("start parsing");}@Overridepublic void startElement(String uri,String localName,String qName,Attributes attr) throws SAXException{System.out.print("<"+qName);int length = attr.getLength();for(int i = 0;i < length;i++){System.out.print(" "+attr.getQName(i)+"="+attr.getValue(i));}System.out.print(">");}@Overridepublic void characters(char[] buf,int start,int length) throws SAXException{System.out.print(new String(buf,start,length));}@Overridepublic void endElement(String uri,String localName,String qName) throws SAXException{System.out.print("</"+qName+">");}}

ok,可以看出,SAX使用基于事件的机制,解析xml文档时要指定处理类,处理类指定遇到开始元素怎么办,遇到文本怎么办,遇到结束怎么办等等,详细资料可以查阅相关文档。
0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 颈椎受凉了很疼怎么办 怀孕了颈椎犯了怎么办 签完协议后悔了怎么办 车秘油耗的数据怎么办 压铸铝模具粘模怎么办 微信红包未退回怎么办 已买的股票配股怎么办 去哪儿网不退款怎么办 专硕学费太贵怎么办 学生饭卡消磁了怎么办 饭卡消磁了钱怎么办 专升本没考上怎么办 平板激活码忘了怎么办 北京买车被骗了怎么办 汽车电池没电了怎么办 汽车完全没电了怎么办 自动挡车没电了怎么办 车缺电打不着火怎么办 车子电脑板坏了怎么办 汽车电脑板坏了怎么办? 小车三角臂坏了怎么办 贵阳摇号中签后怎么办 版面费发票丢了怎么办 当被实名举报了怎么办 玩游戏手老出汗怎么办 智慧树密码忘了怎么办 汽车还完贷款后怎么办 魅蓝note5耗电快怎么办 电脑开机键坏了怎么办 机箱开机键坏了怎么办 起诉后被告不来怎么办 40岁头发全白了怎么办 30岁头发全白了怎么办 领导总是找我茬怎么办 领导想把我整走怎么办 被公司降职降薪怎么办 工作中被降职了怎么办 高中毕业出国留学档案怎么办 汽车智能钥匙丢了怎么办 车子钥匙没电了怎么办 奔驰s级维修太贵怎么办