zoukankan      html  css  js  c++  java
  • JavaWeb--XML的解析(1)

    一、XML解析的技术

    1. DOM
    2. SAX

    针对这两种解析技术,官方以及其他组织提供了不同的实现方式

    常见的解析方式有如下三种:

    a. sun公司提供的jaxp

    b. dom4j组织提供的dom4j

    c. jdom组织提供的jdom

    二、dom VS sax

     dom方式解析
    			* 根据xml的层级结构在内存中分配一个树形结构,把xml的标签,属性和文本都封装成对象
    			* 缺点:如果文件过大,造成内存溢出
    			* 优点:很方便实现增删改操作
    
     sax方式解析
    			* 采用事件驱动,边读边解析:从上到下,一行一行的解析,解析到某一个对象,返回对象名称
    			* 缺点:不能实现增删改操作
    			* 优点:如果文件过大,不会造成内存溢出,方便实现查询操作
    

    三、jaxp所依赖的类

    jaxp是javase的一部分
    jaxp解析器在jdk的javax.xml.parsers包里面

    Dom技术所依赖的两个类:
    	DocumentBuilderFactory: 解析器工厂类。这是一个抽象类,不能实例化
    					   通过newInstance() 方法来获取 DocumentBuilderFactory 的实例。
    	DocumentBuilder  : 解析器类。这个类也是一个抽象类,不能实例化
    				 此类的实例可以从 DocumentBuilderFactory.newDocumentBuilder() 方法获取
    
    sax技术所依赖的两个类:
    	SAXParserFactory: 解析器工厂。实例 newInstance() 方法得到
    	SAXParser:解析器类。实例可以从 SAXParserFactory.newSAXParser() 方法获得
    

    四、jaxp利用DOM技术解析XML文件实例

    现有如下xml文件

    <?xml version="1.0" encoding="UTF-8" standalone="no"?>
    <person>
    	<p>
    		<name>zhangsan</name>
    	</p>
    	
    	<p>
    		<name>lisi</name>
    		<gender>m</gender>
    	</p>
    </person>
    

    操作一:查询xml文件中所有name元素的文本值

    private static void selectAll() throws Exception {
    		//创建解析器工厂对象
    		DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
    		
    		//获取解析器对象
    		DocumentBuilder builder = builderFactory.newDocumentBuilder();
    		
    		//获取解析后的document对象
    		Document doc = builder.parse("F:/MyEclipse10.7/Day05/src/testJaxp/person.xml");
    		
    		//获取所有name元素
    		NodeList list = doc.getElementsByTagName("name");
    		
    		//输出name元素中的文本对象值
    		Node temp = null;
    		for(int i=0; i<list.getLength(); i++){
    			temp = list.item(i);					//获取每一个Node对象
    			String str = temp.getTextContent();		//获取每一个Node对象的content
    			System.out.println(str);
    		}
    }
    

    所用到的方法:

    DocumentBuilderFactory.newInstance():创建解析器工厂类实例
    builderFactory.newDocumentBuilder():创建解析器实例
    builder.parse:解析器调用解析方法,返回解析后的Document对象
    doc.getElementsByTagName("标签名"):document对象调用该方法,获取所有指定标签名的标签,返回类型为NodeList
    list.getLength():NodeList对象调用该方法,返回该List的长度
    list.item(索引):NodeList对象调用该方法,根据下标返回指定Node对象
    getTextContent():标签对象调用该方法,返回该标签的文本值
    

    操作二:在第一个p元素中插入一个gender元素,其中gender元素的文本值为f

    public static void addGender() throws Exception{
    		//获取解析器工厂对象
    		DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
    		
    		//获取解析器对象
    		DocumentBuilder builder = builderFactory.newDocumentBuilder();
    		
    		//获取解析后的document对象
    		Document doc = builder.parse("F:/MyEclipse10.7/Day05/src/testJaxp/person.xml");
    		
    		//获取第一个p元素
    		NodeList list = doc.getElementsByTagName("p");
    		Node p1 = list.item(0);
    		
    		//创建一个gender元素对象
    		Element gender1 = doc.createElement("gender");
    		
    		//创建一个文本对象
    		Text text1 = doc.createTextNode("f");
    		
    		//将文本对象加入gender元素
    		gender1.appendChild(text1);
    		
    		//将gender元素加入到p元素
    		p1.appendChild(gender1);
    		
    		//获取回写工厂对象
    		TransformerFactory transformerFactory = TransformerFactory.newInstance();
    		
    		//获取回写对象
    		Transformer transformer = transformerFactory.newTransformer();
    		
    		//调用回写方法将内存中的document对象写入到xml文件
    		transformer.transform(new DOMSource(doc), new StreamResult("F:/MyEclipse10.7/Day05/src/testJaxp/person.xml"));
    }
    

    所用到的方法:

    doc.createElement("标签名"):Document对象调用该方法,返回创建好的标签对象
    doc.createTextNode("文本值"):Document对象调用该方法,返回创建好的文本对象
    appendChild(对象名):父类对象调用该方法,将指定对象名的对象插入到该父类对象
    TransformerFactory.newInstance():获取回写工厂类对象
    transformerFactory.newTransformer():获取回写对象
    transformer.transform(new DOMSource(doc), new StreamResult("F:/MyEclipse10.7/Day05/src/testJaxp/person.xml")):
    回写对象调用该回写方法,参数分别为源对象,和目的对象
    参数一:Source的实现类
    参数二:Result的实现类
    

    操作三:修改第一个gender元素中的content对象为m

    public static void modifyGender() throws Exception{
    		//获取解析器工厂对象
    		DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
    		
    		//获取解析器对象
    		DocumentBuilder builder = builderFactory.newDocumentBuilder();
    		
    		//获取解析后的document对象
    		Document doc = builder.parse("F:/MyEclipse10.7/Day05/src/testJaxp/person.xml");
    		
    		//获取第一个gender元素
    		Node gender = doc.getElementsByTagName("gender").item(0);
    		
    		//使用setTextContent方法修改文本对象内容
    		gender.setTextContent("m");
    		
    		//回写
    		TransformerFactory formerFactory = TransformerFactory.newInstance();
    		Transformer transformer = formerFactory.newTransformer();
    		transformer.transform(new DOMSource(doc), new StreamResult("F:/MyEclipse10.7/Day05/src/testJaxp/person.xml"));
    	}
    

    用到的方法:

    setTextContent("文本内容"):标签对象调用该方法,修改自己的文本值
    
    

    操作四:删除第一个p1元素下面的gender元素

    public static void removeGender() throws Exception{
    		//获取解析器工厂对象
    		DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
    		
    		//获取解析器 对象
    		DocumentBuilder builder = builderFactory.newDocumentBuilder();
    		
    		//获取解析后的document对象
    		Document doc = builder.parse("F:/MyEclipse10.7/Day05/src/testJaxp/person.xml");
    		
    		//获取gender元素
    		Node gender = doc.getElementsByTagName("gender").item(0);
    		
    		//获取gender得父节点
    		Node p = gender.getParentNode();
    		
    		//父节点使用removeChild方法
    		p.removeChild(gender);
    		
    		//回写
    		TransformerFactory formerFactory = TransformerFactory.newInstance();
    		Transformer transformer = formerFactory.newTransformer();
    		transformer.transform(new DOMSource(doc), new StreamResult("F:/MyEclipse10.7/Day05/src/testJaxp/person.xml"));
    }
    
    

    用到的方法:

    getParentNode():标签对象调用该方法,获取自己的父标签
    removeChild(标签对象名):父标签调用该方法,删除指定标签名的子标签
    
    

    五、jaxp利用SAX技术解析XML文件实例

    1. 创建解析器,并执行parse方法的实例
    public class TeachSax {
    	public static void main(String[] args) throws Exception {
    		/*
    		 * 1、创建解析器工厂
    		 * 2、创建解析器
    		 * 3、执行parse方法
    		 * */
    		//创建解析器工厂
    		SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
    		//创建解析器
    		SAXParser saxParser = saxParserFactory.newSAXParser();
    		//执行parse方法
    		saxParser.parse("F:/MyEclipse10.7/Day06/src/zuobiao/sax/person.xml", new MyDefault1());	
    	}
    }
    
    /**
    	自己创建一个类,继承DefaultHandler
    	重写类里面的三个方法(有时候需要5个)
    */
    class MyDefault1 extends DefaultHandler {
    	@Override
    	public void startElement(String uri, String localName, String qName,
    			Attributes attributes) throws SAXException {
    		System.out.print("<"+qName+">");
    	}
    	
    	@Override
    	public void characters(char[] ch, int start, int length)
    			throws SAXException {
    		System.out.print(new String(ch,start,length));
    	}
    
    	@Override
    	public void endElement(String uri, String localName, String qName)
    			throws SAXException {
    		System.out.print("</"+qName+">");
    	}
    }
    
    

    用到的方法:

    SAXParserFactory.newInstance():创建解析类工厂对象
    saxParserFactory.newSAXParser():获取解析类对象
    parse(参数1, 参数2):解析XML文档
    两个参数
    	- 第一个参数:xml的路径
    	- 第二个参数:事件处理器(该处理器需要继承自DefaultHandler,并重写里面的方法)
    	
    事件处理类:
    DefaultHandler	
    	- startDocument:当XML文档开始解析时该方法被自动调用
    	- startElement:当开始解析一个元素时,该方法被自动调用
    	- characters:当解析到文本内容时,该方法被自动调用
    	- endElement:当解析一个元素结束时,该方法被自动调用
    	- endDocument:当XML文档解析结束时该方法被自动调用
    
    
    1. sax解析xml文档操作实例

    现有如下xml文件

    <?xml version="1.0" encoding="UTF-8"?>
    <person> 
      <p1> 
        <name>zhangsan</name>  
        <age>20</age>  
      </p1>  
      <p1> 
        <name>lisi</name>  
        <age>30</age> 
      </p1> 
    </person>
    
    

    操作一:输出xml文件中的所有内容

    事件处理类如下:

    class MyDefaultHandler1 extends DefaultHandler{
    	@Override
    	public void startDocument() throws SAXException {
    		System.out.println("<?xml version='1.0' encoding='utf-8'?>");
    	}
        
    	@Override
    	public void startElement(String uri, String localName, String qName,
    			Attributes attributes) throws SAXException {
    		System.out.print("<"+qName+">");
    	}
    	
    	@Override
    	public void characters(char[] ch, int start, int length)
    			throws SAXException {
    		System.out.print(new String(ch,start,length));
    	}
    	
    	@Override
    	public void endElement(String uri, String localName, String qName)
    			throws SAXException {
    		System.out.print("</"+qName+">");
    	}
        
        @Override
    	public void characters(char[] ch, int start, int length)
    				throws SAXException {
    		System.out.print(new String(ch, start, length));
    	}
    }
    
    

    main方法中调用:

    public class TestSax {
    	public static void main(String[] args) throws Exception{
    		//获取SaxParserFactory对象
    		SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
    		
    		//获取SaxParser对象
    		SAXParser parser = saxParserFactory.newSAXParser();
    		
    		//使用parser方法解析xml文件
    		parser.parse("F:/MyEclipse10.7/Day06/src/zuobiao/sax/person.xml", new MyDefaultHandler1());
    	}
    }
    
    

    操作二:输出指定索引的name标签文本值

    事件处理类如下:

    class MyDefaultHandler2 extends DefaultHandler{
    	boolean flag = false;	//使用标记来记录是否为name标签
    	int index = 0;		    //使用index来继承name标签的索引值
    	
    	@Override
    	public void startElement(String uri, String localName, String qName,
    			Attributes attributes) throws SAXException {
    		if("name".equals(qName)){
    			this.flag = true;
    			index++;
    		}
    	}
    	
    	@Override
    	public void characters(char[] ch, int start, int length)
    			throws SAXException {
    		if(flag && (index==2)){
    			System.out.println(new String(ch,start,length));
    		}
    	}
    	
    	@Override
    	public void endElement(String uri, String localName, String qName)
    			throws SAXException {
    		if("name".equals(qName)){
    			this.flag = false;
    		}
    	}
    }
    
    

    main方法中调用同上,故省略。

    参考博文在此

    Java新手,若有错误,欢迎指正!

  • 相关阅读:
    C#中静态与非静态方法比较
    Hibernate学习之路-- -映射 继承关系(subclass , joined-subclass,union-subclass )
    网络协议概述:物理层、连接层、网络层、传输层、应用层详解
    phpstorm xdebug配置
    eclipse修改内存大小
    Session机制详解
    java把html标签字符转普通字符(反转换成html标签)(摘抄)
    JAVA调用WCF
    RabbitMQ入门与使用篇
    大话程序猿眼里的高并发
  • 原文地址:https://www.cnblogs.com/Java-biao/p/12675069.html
Copyright © 2011-2022 走看看