在不同的语言中,XML的解析方法都是一样的,只不过实现的语法不同而已。基本的解析方式有两种,一种是SAX,另外一种是DOM,SAX是基于事件流的解析,DOM是基于XML文档结构的解析。
为 XML 文档的已解析版本定义了一组接口。解析器读入整个文档,然后构建一个驻留内存的树结构,然后代码就可以使用 DOM 接口来操作这个树结构。优点:整个文档树在内存中,便于操作;支持删除、修改、重新排列等多种功能;缺点:将整个文档调入内存(包括无用的节点),浪费时间和空间;使用场合:一旦解析了文档还需多次访问这些数据;硬件资源充足(内存、CPU)。
在DOM解析中有四个核心接口:
1.Document:代表整个XML文档,表示整棵DOM树的根,提供了对文档中数据进行访问和操作的入口,通过Document节点可以访问XML文件中所有的元素内容。
Document接口常用方法:
2.Node:每一个Node接口代表了DOM树中的一个节点,DOM操作的核心接口有很大一部分是从Node继承过来的,例如:Document、Element、Attr。
Node接口常用方法:
3.NodeList
此接口表示一个节点的集合,一般用于表示有顺序关系的一组节点,例如一个节点的子节点,当文档改变时会影响到NodeList集合。
4.NamedNodeMap
表示一组节点和名称的一一对应关系,主要用于属性节点的表示。
DOM解析的步骤:
<1.建立DocumentBuilderFactory : DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
<2.建立DocumentBuilder: DocumentBuilder builder = factory.newDocumentBuilder();
<3.建立Document :Document doc = builder.parse("要读取的文件路径");
<4.建立NodeList : NodeList nl = doc.getElementsByTAgName("读取节点");
<5.进行XML信息读取
要读取的XML文件:
<?xml version="1.0" encoding="GBK"?> <addresslist> <linkman> <name>疯子乙</name> <email>[email protected]</email> </linkman> <linkman> <name>Lunatic</name> <email><span style="font-family: Arial, Helvetica, sans-serif;">lunatictwo</span><span style="font-family: Arial, Helvetica, sans-serif;">@163.com</email></span> </linkman> </addresslist>
实例:
<pre name="code" class="java">package org.lxh.xml.dom ; import java.io.* ; import org.w3c.dom.* ; import javax.xml.parsers.* ; public class DOMDemo02 { public static void main(String args[]) throws Exception { // 取得DocumentBuilderFactory类的对象 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance() ; // 取得DocumentBuilder类的对象 DocumentBuilder build = factory.newDocumentBuilder() ; Document doc = build.parse(new File("D:" + File.separator + "dom_demo_01.xml")) ; // 得到所有的linkman节点 NodeList nl = doc.getElementsByTagName("linkman") ; for(int x=0;x<nl.getLength();x++){ Element e = (Element) nl.item(x) ; // 取出每一个元素 System.out.println("姓名:" + e.getElementsByTagName("name").item(0).getFirstChild().getNodeValue()) ; System.out.println("邮箱:" + e.getElementsByTagName("email").item(0).getFirstChild().getNodeValue()) ; } } }
SAX主要事件:
如果在开发中要使用SAX解析,则首先应该编写一个SAX解析器,再直接定义一个类,并且使该类继承自DefaultHandler类,同时覆写上表中的方法即可。
SAX解析器的编写:
package org.lxh.xml.sax ; import org.xml.sax.* ; import org.xml.sax.helpers.* ; public class MySAX extends DefaultHandler { public void startDocument() throws SAXException{ System.out.println("<?xml version=\"1.0\" encoding=\"GBK\">") ; } public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException{ System.out.print("<") ; System.out.print(qName) ; if(attributes != null){ // 如果存在了属性 for(int x=0;x<attributes.getLength();x++){ System.out.print(" " + attributes.getQName(x) + "=\"" + attributes.getValue(x) + "\"") ; } } System.out.print(">") ; } public void endElement(String uri, String localName, String qName) throws SAXException{ System.out.print("<") ; System.out.print(qName) ; System.out.print(">") ; } public void characters(char[] ch, int start, int length) throws SAXException{ System.out.print(new String(ch,start,length)) ; } public void endDocument() throws SAXException{ System.out.println("文档结束。。。") ; } }
<?xml version="1.0" encoding="GBK"?> <addresslist> <linkman id="001"> <name>疯子乙</name> <email>[email protected]</email> </linkman> <linkman id="002"> <name>MLDN</name> <email>[email protected]</email> </linkman> </addresslist>
package org.lxh.xml.sax ; import java.io.* ; import javax.xml.parsers.* ; public class TestSAX { public static void main(String args[]) throws Exception { // 建立SAX解析工厂 SAXParserFactory factory = SAXParserFactory.newInstance() ; SAXParser parser = factory.newSAXParser() ; parser.parse("d:" + File.separator + "sax_demo.xml",new MySAX()) ; } }
JDOM是一个开源的Java组件,JDOM是为Java优化的,为使用XML文件提供了一个低内耗的方法。
JDOM的主要操作类:
使用JDOM生成XML文件:
package org.lxh.xml.jdom ; import java.io.* ; import org.jdom.* ; import org.jdom.output.* ; public class WriteXML { public static void main(String args[]) throws Exception { Element addresslist = new Element("addresslist") ; Element linkman = new Element("linkman") ; Element name = new Element("name") ; Element email = new Element("email") ; Attribute id = new Attribute("id","lxh") ; Document doc = new Document(addresslist) ; // 定义Document对象 name.setText("疯子乙") ; name.setAttribute(id) ; // 将属性设置到元素之中 email.setText("[email protected]") ; linkman.addContent(name) ; // 设置关系 linkman.addContent(email) ; addresslist.addContent(linkman) ; XMLOutputter out = new XMLOutputter() ; out.setFormat(out.getFormat().setEncoding("GBK")) ; // 表示的是设置编码 out.output(doc,new FileOutputStream(new File("D:" + File.separator + "address.xml"))) ; } }
package org.lxh.xml.jdom ; import java.io.* ; import java.util.* ; import org.jdom.* ; import org.jdom.input.* ; public class ReadXML { public static void main(String args[]) throws Exception { SAXBuilder builder = new SAXBuilder() ; Document read_doc = builder.build(new File("D:" + File.separator + "address.xml")) ; Element root = read_doc.getRootElement() ; // 取得根 List list = root.getChildren("linkman") ; // 得到所有的linkman for(int x=0;x<list.size();x++){ Element e = (Element) list.get(x) ; String name = e.getChildText("name") ; // 得到name子节点的内容 String id = e.getChild("name").getAttribute("id").getValue() ; String email = e.getChildText("email") ; System.out.println("-------------- 联系人 -------------") ; System.out.println("姓名:" + name + ",编号:" + id) ; System.out.println("EMAIL:" + email) ; System.out.println("-----------------------------------") ; System.out.println() ; } } }
package org.lxh.xml.dom4j ; import java.io.* ; import org.dom4j.* ; import org.dom4j.io.* ; public class DOM4JWriter { public static void main(String args[]) throws Exception { Document doc = DocumentHelper.createDocument() ; Element addresslist = doc.addElement("addresslist") ; // 现在定义一个根节点 Element linkman = addresslist.addElement("linkman") ; Element name = linkman.addElement("name") ; Element email = linkman.addElement("email") ; name.setText("疯子乙") ; email.setText("email") ; OutputFormat format = OutputFormat.createPrettyPrint() ; format.setEncoding("GBK") ; XMLWriter writer = new XMLWriter(new FileOutputStream(new File("d:" + File.separator + "output.xml")),format) ; writer.write(doc) ; // 进行输出 writer.close() ; } }解析XML文件:
package org.lxh.xml.dom4j ; import java.io.* ; import java.util.* ; import org.dom4j.* ; import org.dom4j.io.* ; public class DOM4JReader { public static void main(String args[]) throws Exception { File file = new File("d:" + File.separator + "output.xml") ; SAXReader reader = new SAXReader() ; Document doc = reader.read(file) ; // 读取XML文件 // JDOM操作的时候是要取得根节点 Element root = doc.getRootElement() ; // 取得根节点 // 现在应该根据根节点找到全部的子节点,linkman Iterator iter = root.elementIterator() ; while(iter.hasNext()){ Element linkman = (Element) iter.next() ; System.out.println("姓名:" + linkman.elementText("name")) ; System.out.println("邮件:" + linkman.elementText("email")) ; } } }