秒速pk10app开户 _Java解析XML文件的方式

  • 时间:
  • 浏览:1
  • 来源:完美娱乐网_提供678辅助网技术_玩游戏赚钱资讯

    在项目里,让.我 往往会把已经 配置信息倒进xml文件里,不可能 各部门间会通过xml文件来交换业务数据,也不 有以前让.我 会遇到“解析xml文件”的需求。一般来讲,有基于DOM树和SAX的两种解析xml文件的最好的最好的办法,在这偏离 里,将分别给让.我 演示通过这两种最好的最好的办法解析xml文件的一般步骤。

1 XML的文件格式

    XML是可扩展标记语言(Extensible Markup Language)的缩写,在其中,开始英文英文标签和开始英文英文标签还要配套地再次出先,让.我 来看下book.xml两种例子。   

1	<?xml version="1.0" encoding="UTF-8" standalone="no"?>
2	<books>
3	    <book id="01">
4	        <name>Java</name>
5	        <price>15</price>
6	        <memo>good book</memo>
7	    </book>
8	    <book id="02">
9	       <name>FrameWork</name>
10	       <price>20</price>
11	       <memo>new book</memo>
12	    </book>
13	</books>

    整个xml文件是另另一个多文档(document),其中第1行表示文件头,在第2和第13行里,让.我 能看后配套再次出先的books标签,从标签头到标签尾的偏离 以前 们称之为元素(element)。

    也不 让.我 后能 以前 说,在books元素里,让.我 分别于第3到第7行和第8到第12行定义了另另一个多book元素,在每个book元素,比如从第4到第6行,又中有 着另一个元素,比如第一本书的name元素是<name>Java</name>,它的name元素值是Java。

    在第3行里,让.我 还能看后元素里的属性(attribute),比如两种book元素具有id两种属性,具体id的属性值是01。

2 基于DOM树的解析最好的最好的办法

    DOM是Document Object Model(文档对象模型)的缩写,在基于DOM树的解析最好的最好的办法里,解析代码会先把xml文档读到内存里,并整理成DOM树的形式,已经 再读取。根据以前偏离 里给出的book.xml文档,让.我 后能 绘制出如下形式的DOM树。

    

     其中,books属于根(root)结点,也叫根元素,不可能 它中有 着另另一个多book元素,也不 第二层是另另一个多book结点,每个book元素中有 着另一个元素,也不 第三层是6个元素。在下面的ParserXmlByDom.java的代码里,让.我 来看下通过DOM树最好的最好的办法解析book.xml文档的完全步骤。

1	//省略import相关类库的代码
2	public class ParserXmlByDom {
3		public static void main(String[] args) {
4	        //创建DOM工厂
5			DocumentBuilderFactory domFactory=DocumentBuilderFactory.newInstance();
6			InputStream input = null;
7	        try {
8	            //通过DOM工厂获得DOM解析器
9	            DocumentBuilder domBuilder=domFactory.newDocumentBuilder();
10	            //把XML文档转化为输入流
11	            input=new FileInputStream("src/book.xml");            
12	            //解析XML文档的输入流,得到另另一个多Document
13	            Document doc=domBuilder.parse(input);

    从第5行到第13行,让.我 完成了用DOM树解析XML文件的准备工作,具体包括,在第5行里创建了DOM工厂,在第9行通过DOM工厂创建了解析xml文件DocumentBuilder类型对象,在第11行把待解析的xml文件倒进到另另一个多InputStream类型的对象里,在第13行通过parse最好的最好的办法把xml文档解析成另另一个多基于DOM树底部形态的Document类型对象。    

14	            //得到XML文档的根节点,不到根节点是Element类型
15	            Element root=doc.getDocumentElement();
16	            // 得到子节点
17	            NodeList books = root.getChildNodes();

    整个XML文件中有 在第13行定义的doc对象里,在第15行里,让.我 通过getDocumentElement最好的最好的办法得到了根节点(也也不books节点),在第17行,通过getChildNoes最好的最好的办法得到该books节点下的所有子节点,已经 开始英文英文解析整个xml文档。

    还要说明的是,在解析前,让.我 会通过观察xml文档来了解其中的元素名和属性名,也不 在后继的代码里,让.我 会针对元素名和属性名进行编程。    

18	            if(books!=null){
19	                for(int i=0;i<books.getLength();i++){
20	                    Node book=books.item(i);
21	                    //获取id属性                      
22	                    if(book.getNodeType()==Node.ELEMENT_NODE){
23	                        String id=book.getAttributes().getNamedItem("id").getNodeValue();
24	                        System.out.println("id is:" + id);
25	                        //遍历book下的子节点
26	                        for(Node node=book.getFirstChild(); node!=null;node=node.getNextSibling()){
27	if(node.getNodeType()==Node.ELEMENT_NODE){
28	    //依次读取book里的name,price和memo另另一个多子元素
29	    if(node.getNodeName().equals("name")){
200	        String name=node.getFirstChild().getNodeValue();
31	        System.out.println("name is:" + name);                                    
32	    }
33	    if(node.getNodeName().equals("price")){
34	        String price=node.getFirstChild().getNodeValue();
35	        System.out.println("price is:" + price);
36	    }
37	    if(node.getNodeName().equals("memo")){
38	          String memo=node.getFirstChild().getNodeValue();
39	          System.out.println("memo is:" + memo);
40	     }
41	   }
42	 }
43	}
44	}
45	}

    第19行的for循环里,让.我 是遍历book元素通过观察xml文件,让.我 发现book元素再次出先了2次,所有两种循环会运行两次,已经 ,book元素另另一个多多id属性,所有让.我 还要通过第23行的代码,得到id属性的值。

    在文档里,book元素有另一个子节点,分别是name,price和memo,也不 在代码的26行里,再次使用for循环遍历其中的子节点。在遍历时,让.我 通过29到32行的代码获取到了book元素里name的值,通过相似 的代码后继的33到40行代码里得到了price和memo两种个多多元素的值。    

46	        } catch (ParserConfigurationException e) {
47	            e.printStackTrace();
48	        } catch (FileNotFoundException e) {
49	            e.printStackTrace();
200	        } catch (IOException e) {
51	            e.printStackTrace();
52	        } catch (SAXException e) {			
53				e.printStackTrace();
54			} catch (Exception e) {			
55				e.printStackTrace();
56			}
57	        //在finally里关闭io流 
58	        finally{
59	        	try {
200					input.close();
61				} catch (IOException e) {
62					e.printStackTrace();
63				}
64	        }
65		}
66	}

    同样地,在解析完成后,在finally从句里,让.我 关闭了以前用到的IO流(input对象)。

3 基于事件的解析最好的最好的办法

    SAX是Simple API for XML的缩写,不同于DOM的文档驱动,它是事件驱动的,也也不说,它是两种基于回调(callback)函数的解析最好的最好的办法,比如开始英文英文解析xml文档时,会调用让.我 被委托人定义的startDocument函数,从下表里,让.我 能看后基于SAX最好的最好的办法里的各种回调函数以及它们被调用的时间点。

函数名

调用时间点

startDocument

开始英文英文解析xml文档时(解析xml文档第另另一个多字符时)会被调用

endDocument

当解析完xml文档时(解析到xml文档最后另另一个多字符时)会被调用

startElement

当解析到开始英文英文标签不会被调用,比如在解析“<name>FrameWork</name>”两种element时,当读到开始英文英文标签“<name>”时,会被调用

endElement

当解析到开始英文英文标签不会被调用,比如在解析“<name>FrameWork</name>”两种element时,当读到开始英文英文标签“</name>”时,会被调用

characters

1行开始英文英文后,遇到开始英文英文或开始英文英文标签以前居于字符,则会调用

2另另一个多标签之间,居于字符,则会调用,比如在解析“<name>FrameWork</name>”时,发现居于FrameWork,则会被调用

3标签和行开始英文英文符以前居于字符,则会调用

    从上表里让.我 能看后characters最好的最好的办法会在多个场合被回调,但让.我 最期望的调用场景是第2种,这就要求让.我 最好在解析xml文档前整理下它的格式,尽量解决第1和第3种状况。在ParserXmlBySAX.java两种案例中,让.我 通过了编写上述的回调函数,实现了SAX最好的最好的办法解析xml文档的功能。    

1	//省略import的代码
2	//基于SAX的解析代码还要继承DefaultHandler类
3	public class ParserXmlBySAX extends DefaultHandler{
4		// 记录当前解析到的节点名
5		private String tagName; 
6		//主最好的最好的办法
7		public static void main(String[] argv) {
8			String uri = "src/book.xml";
9			try {
10				SAXParserFactory parserFactory = SAXParserFactory.newInstance();
11				ParserXmlBySAX myParser = new ParserXmlBySAX();
12				SAXParser parser = parserFactory.newSAXParser();
13				parser.parse(uri, myParser);
14			} catch (IOException ex) {
15				ex.printStackTrace();
16			} catch (SAXException ex) {
17				ex.printStackTrace();
18			} catch (ParserConfigurationException ex) {
19				ex.printStackTrace();
20			} catch (FactoryConfigurationError ex) {
21				ex.printStackTrace();
22			}		
23		}

    在main最好的最好的办法的第8行里,让.我 指定了待解析xml文档的路径和文件名,在第10行里,让.我 创建了SAXParserFactory两种类型的SAX解析工厂对象。在第12行,让.我 通过SAX解析工厂对象,创建了SAXParser两种类型的解析类。在第13行,通过了parse最好的最好的办法启动了解析。

    在上文里让.我 就不可能 知道,在SAX的最好的最好的办法里,是通过调用各种回调函数来完成解析的,也不 在代码里,让.我 还得自定义各个回调函数,代码如下。    

// 解决到文档结尾时,直接输出,不做任何动作
25		public void endDocument() throws SAXException {
26			System.out.println("endDocument");
27		}
28		// 解决到开始英文英文标签时,把记录当前标签名的tagName设置成null
29		public void endElement(String uri, String localName, String qName) throws SAXException {
200			tagName = null;
31		}
32		// 开始英文英文解决文档时,直接输出,不做任何动作
33		public void startDocument() throws SAXException {
34			System.out.println("startDocument");		
35		}
36		// 解决开始英文英文标签
37		public void startElement(String uri, String localName, String name,Attributes attributes) throws SAXException {	
38			if ("book".equals(name)) { //解析book标签的属性 
39	            for (int i = 0; i < attributes.getLength(); i++) {
40	                System.out.println("attribute name is:" + attributes.getLocalName(i)  + "  attribute value:" + attributes.getValue(i)); 
41	            }            
42	        }
43	        //把当前标签的名字记录到tagName两种变量里  
44			tagName = name; 
45		}
46	    //通过两种最好的最好的办法解析book的另另一个多子元素的值
47		public void characters(char[] ch, int start, int length)  
48	            throws SAXException {  
49	        if(this.tagName!=null){  
200	            String val=new String(ch,start,length);            
51	            //不可能

是name,price或memo,则输出它们的值
52	            if("name".equals(tagName))
53	            { System.out.println("name is:" + val);  }
54	            if("price".equals(tagName))
55	            { System.out.println("price is:" + val); }
56	            if("memo".equals(tagName))
57	            { System.out.println("memo is:" + val);  }
58	        }  
59	    }
200	}

    让.我 用tagName来保存当前的标签名,是为了解析book元素的name,price和memo两种个多多子元素。

    <name>FrameWork</name>

    比如当解析到name两种开始英文英文标签时,在第44行里,startElement会把tagname值设置成name,当解析到FramWork时,不可能 它中有 在另另一个多标签之间,也不 会被触发第47行的characters最好的最好的办法,在其中的第52行的if判断里,不可能 得知当前的标签名是name,也不 会输出FrameWork两种name元素的值,当解析到</name>两种开始英文英文标签时,会触发第29行的endElement最好的最好的办法,在其中的200行里,会把tagName值清空。

    这段代码的输出结果如下,其中第1行和第10行分别是在开始英文英文解析和完成解析时输出的。

    第2行针对id属性的输出是在startElement最好的最好的办法的第40行里被打印的,第3到第5行针对另一个book子元素的输出是在characters最好的最好的办法里被打印的。

    第2到第5行是针对第另另一个多book元素的输出,而第6到第9行是针对第另另一个多book。    

1	startDocument
2	attribute name is:id  attribute value:01
3	name is:Java
4	price is:15
5	memo is:good book
6	attribute name is:id  attribute value:02
7	name is:FrameWork
8	price is:20
9	memo is:new book
10	endDocument

4 DOM和SAX两种解析最好的最好的办法的应用场景

    在基于DOM的最好的最好的办法里,不可能 让.我 会把整个xml文档以DOM树的最好的最好的办法装载到内存里,也不 后能 边解析边修改,已经 还能再次解析不可能 被解析过的内容。

    而在SAX的最好的最好的办法里,不可能 让.我 是以基于回调函数的最好的最好的办法来解析,也不 不想还要把整个文档载入到内存,以前 能节省内存资源。

    也不 说,选折 DOM 还是 SAX,这取决于如下另另一个多个因素。

    第一,不可能 让.我 在解析时还打算更新xml里的数据,没有 建议使用DOM最好的最好的办法。

    第二,不可能 待解析的文件过大,把它完全装载到内存时不可能 会影响到内存性能,没有 建议使用SAX的最好的最好的办法。

    第三,不可能 让.我 对解析的带宽有一定的要求,没有 建议使用SAX最好的最好的办法,不可能 它比DOM最好的最好的办法要快些。