一、 DOM 文档对象模式
1.DOM特点:以树型结构访问XML文档。 一棵DOM树包含全部元素节点和文本节点。可以前后遍历树中的每一个节点。
整个文档树在内存中,便于操作;支持删除、修改、重新排列等多种功能。
将整个文档调入内存(包括无用的节点),浪费时间和空间。
一旦解析了文档还需多次访问这些数据;硬件资源充足(内存、cpu)情况下使用。
2.DOM树与节点
XML文档被解析成树型结构。
树由节点组成。共有12种不同的节点。
节点可以包含其他节点(依赖于节点的类型)。
父节点包含子节点。叶子节点没有子节点。
3.节点类型
Document node 包含:一个根Element节点。一个或多个处理指令节点。 Document Fragment node Element node包含:其他Element节点。若干个Text节点。若干个Attribute节点。 Attribute node 包含:一个Text节点。 Text node Comment node Processing instruction node Document type node Entity node Entity reference node CDATA section node Notation node
二、 SAX 基于事件处理模式
解析器向一个事件处理程序发送事件,比如元素开始和元素结束,而事件处理器则处理该信息。然后应用程序本身就能够处理该数据。原始的文档仍然保留完好无损。
<![CDATA[################## SAX处理器(遍历XML) ###########################]]> 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.SAXParseException; import org.xml.sax.helpers.DefaultHandler; public class TestSAXParser { /** 基于SAX方式解析XML文档 */ public static void main(String[] args) throws SAXException,ParserConfigurationException,IOException{ SAXParserFactory factory = SAXParserFactory.newInstance(); //创建SAX解析器工厂 factory.setValidating(true); //让error方法生效 SAXParser parser = factory.newSAXParser(); //生成一个具体的SAX解析器 parser.parse("src/file/student.xml",new XMLreader()); //开始解析 }} class XMLreader extends DefaultHandler { // 只需覆盖我们感兴趣的方法 private int counter = 0;// 定义一个计数器,保存XML文档触发事件的次数 @Override // 文档开始事件触发 public void startDocument() throws SAXException { counter++; System.out.println(counter + ".解析XML文件开始...");} @Override // 文档结束事件触发 public void endDocument() throws SAXException { counter++; System.out.println("\r\n"+counter + ".解析XML文件结束...");} @Override // 元素开始事件触发 public void startElement(String uri,String localName,String qName,Attributes atts) throws SAXException { counter++; System.out.print(counter+".<"+qName); for(int i=0; i<atts.getLength();i++){ //读取标志的所有属性 System.out.print(" "+atts.getLocalName(i)+"="+atts.getValue(i)); }System.out.print(">"); } @Override // 元素结束事件触发 public void endElement(String uri,String qName) throws SAXException { counter++; System.out.print(counter +".</"+qName+">");} @Override // 文本事件触发 打印时尽量不要换行,否则很难看 public void characters(char[] ch,int start,int length)throws SAXException { counter++; String text = new String(ch,start,length); // 当前元素的文本值 System.out.print(counter + ".Text=" + text);} @Override //这是可恢复错误。需在SAXParserFactory设置有效性错误才能生效 public void error(SAXParseException e) throws SAXException { System.out.println("xml文档有效性错误:"+e);} @Override //严重错误 public void fatalError(SAXParseException e) throws SAXException { System.out.println("xml文档严重的有效性错误:"+e);} } <![CDATA[################## SAX处理器(遍历XML)结束 ###########################]]>
三、 DOM
<![CDATA[######################### DOM遍历方式 ###########################]]> 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.Attr; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.NamedNodeMap; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.xml.sax.SAXException; /**基于DOM的解析XML文档*/ public class TestDOMParser { public static void main(String[] args) throws ParserConfigurationException,SAXException,IOException{ //创建一个DOM解析器工厂 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); //从工厂中生成一个DOM解析器; throws ParserConfigurationException DocumentBuilder builder = factory.newDocumentBuilder(); //绑定需要解析的XML文件 File xmlFile = new File("src/file/student.xml");//相对地址,相对于这个工程 //开始解析 ;throws SAXException,IOException Document document = builder.parse(xmlFile); //取出唯一的根元素 Element rootElement = document.getDocumentElement(); //调用业务方法: 遍历根元素 printElement(rootElement); } /** 遍历元素,包含: 子元素、属性、文本内容 */ private static void printElement(Element e){ //打印出元素的标签名 System.out.print("<"+e.getTagName()); //获取开始标签的属性 NamedNodeMap attMap = e.getAttributes(); //循环遍历所有的属性 for (int i=0;i<attMap.getLength();i++){ Attr attr = (Attr)attMap.item(i); System.out.print(" "+attr.getName()+"="+attr.getValue());} System.out.print(">"); //获取当前元素的所有子节点 NodeList nl = e.getChildNodes(); for (int j=0;j<nl.getLength();j++){ Node n = nl.item(j); if (Node.ELEMENT_NODE==n.getNodeType()){ printElement((Element)n);//递归调用,以遍历下一个元素 } else { System.out.print(n.getTextContent()); } } //打印结束标签 System.out.print("</"+e.getTagName()+">"); }} <![CDATA[ ###################### DOM遍历 完毕 ##########################]]>