zoukankan      html  css  js  c++  java
  • XML解析

    前言:xml解析主要分为dom解析和sax解析,dom是W3C组织推荐的处理XML文档的一种方式,sax不是官方标准,但它是xml社区事实上的标准(相当于是一个民间标准),几乎

    所有的xml解析器都支持它。dom和sax都是一种模型,都需要使用具体的代码去实现它。dom4j组织根据自己的解析器推出了解析xml的api dom4j,它是一个十分优秀的API,具有

    性能优异、功能强大和极易使用的特点,一经推出就风靡。

    一、sax解析

    1.1sax解析的特点

    sax解析xml文件时,遇到开始标签、结束标签、开始解析文件,文件解析结束,字符内容和空白字符时都会触发各自的方法。

    优点:适合解析大文件,对内存要求不高。轻量级的解析数据方式,效率更高

    缺点:不能随机解析文件,不能修改xml文件,只能进行查询

    在基于sax的程序中,有五个最常用的sax事件

    startDocument() ---> 解析器发现了文档的开始标签
    endDocument()   ---> 解析器发现了文档结束标签
    startElement()  ---> 解析器发现了一个起始标签
    character()     ---> 解析器发现了标签里面的文本值
    endElement()    ---> 解析器发现了一个结束标签

    利用SAX解析xml文档,涉及两个部分:解析器和时间处理器。例如:

    package XMLjiexi;
    
    import java.io.IOException;
    import java.util.ArrayList;
    import java.util.List;
    
    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;
    
    import com.sun.org.apache.xerces.internal.xni.QName;
    
    /*
     使用sax解析去解析xml文件,sax解析的机制为遇到开始标签结束标签开始解析文件,遇到文本内容和空白内容都会触发方法,
     特点:适合解析大文件,对内存要求不高,轻量级的解析,效率更高
     缺点:不能随机修改,只能进行查询,不能随机进行解析,因为是从上到下的解析方式
      */
    public class Saxparse {
    	private List<student> stus;
    	private student stu;
    	public List<student> read(String filePath) {
    		stus=new ArrayList<>();
    		
    		try {
    			//第一步,获取sax解析工厂对象
    			SAXParserFactory factory = SAXParserFactory.newInstance();
    			//第二步,获得sax解析器对象
    			SAXParser parser = factory.newSAXParser();
    			//第三步,利用解析器对象解析xml文件,传的第一个is对象为需要解析的xml文件的路径,第二个对象dh为
    			//sax解析的关键内容,这个内部类写了很多个方法,解析xml文档的方法,我们只需要去实现五个关键的方法。
    			parser.parse(filePath,new DefaultHandler() {
    				String cuurentQname;
    				@Override
    				public void characters(char[] ch, int start, int length) throws SAXException {
    					//System.out.println("获取元素内容");
    					String text=new String(ch, start, length);
    					if("name".equals(this.cuurentQname)) {
    						stu.setName(text);
    					}else if("age".equals(this.cuurentQname)) {
    						stu.setAge(Integer.parseInt(text));
    					}
    				}
    
    				@Override
    				public void endDocument() throws SAXException {
    					System.out.println("文档解析结束");
    				}
    				//当解析到下一个stu时,这个时候已经解析完一个部分了,把这个所有内容保存进list对象stus里面去。
    				@Override
    				public void endElement(String uri, String localName, String qName) throws SAXException {
    						//System.out.println("元素解析结束");
    					if(qName.equals("stu")) {
    						stus.add(stu);
    					}
    					this.cuurentQname=null;
    				}
    
    				@Override
    				public void startDocument() throws SAXException {
    					System.out.println("文档开始解析");
    				}
    				/*各个参数的含义
    				 * uri:命名空间
    				 * localName:不带前缀名
    				 * qName:带前缀名
    				 * attributes:属性对象
    				 */
    				public void startElement(String uri, String localName, String qName, Attributes attributes)
    						throws SAXException {
    						this.cuurentQname=qName;
    					//System.out.println("元素开始解析");
    					if(qName.equals("stu")) {
    						//当解析到stu时,需要创建一个对象去存储接下来会获取到的属性值
    						stu=new student();
    						//属性内容可以通过属性名或者索引来获取属性内容
    						String id = attributes.getValue("id");
    						//属性内容的格式是string类型的,需要把它转换为long内容再存进域对象stu里面。ps:开始设置
    						//stu时的属性为long类型
    						stu.setId(Long.parseLong(id));
    					}
    				}
    				
    			} );
    		} catch (ParserConfigurationException e) {
    			e.printStackTrace();
    		} catch (SAXException e) {
    			e.printStackTrace();
    		} catch (IOException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		}
    		return stus;
    	}
    	public static void main(String[] args) {
    		List<student> stus = new Saxparse().read("src/XMLjiexi/Student.xml");
    		System.out.println(stus.toString());
    	}
    
    }
    

    二、DOM解析

    2.1dom解析的特点

    采用dom解析,会将xml文档全部加载到内存当中,然后将xml文档中的所有内容转化为tree上的节点(对象).

    优点:可以随机解析,可以修改文件,可以创建xml文件

    缺点:适合解析小型文件,对内存要求较高。

    三、dom4j解析

    3.1dom4j解析简介

    dom4j是一个简单、灵活的开放源代码的库。现在很多软件采用的dom4j,使用dom4j开发,需要下载相应的jar包。

    3.2dom4j创建、解析、修改xml文件

    创建一个和遍历一个xml文档

    package XMLjiexi;
    
    import java.io.File;
    import java.io.FileOutputStream;
    import java.util.List;
    
    import org.dom4j.Document;
    import org.dom4j.DocumentHelper;
    import org.dom4j.Element;
    import org.dom4j.io.OutputFormat;
    import org.dom4j.io.SAXReader;
    import org.dom4j.io.XMLWriter;
    /*
     * 使用dom4japi可以创建和解析和修改xml文件,以下是一些创建和修改相关的操作以及注释
     */
    public class Dom4jTest {
    	//创建一个新的xml文件
    	public void createDom(String file){
    		//获得文档对象
    		Document document = DocumentHelper.createDocument();
    		
    		//添加根元素
    		Element root = document.addElement("root");
    		//根元素下面添加子元素及其属性
    		Element city = root.addElement("city");
    		city.addAttribute("name", "上海");
    		//city元素下面添加子元素及其文本值
    		Element num = city.addElement("peopleNumber");
    		num.addText("23343");
    		Element sal = city.addElement("salary");
    		sal.addText("12000");
    		Element city1 = root.addElement("city");
    		city1.addAttribute("name", "北京");
    		//city元素下面添加子元素及其文本值
    		Element num1 = city1.addElement("peopleNumber");
    		num1.addText("11111");
    		Element sal1 = city1.addElement("salary");
    		sal1.addText("14000");
    		try {
    //			输出格式化xml
    			OutputFormat format = OutputFormat.createPrettyPrint();
    			XMLWriter xw = new XMLWriter(new FileOutputStream(new File(file)),format);
    			xw.write(document);
    			xw.flush();
    			xw.close();
    		
    		} catch (Exception e) {
    			e.printStackTrace();
    		} 
    	}
    	
    	
    	public void readXML(String filePath){
    		
    		try {
    			//获得一个SAXReader对象
    			SAXReader reader = new SAXReader();
    			File file = new File(filePath);
    			//读取这个要解析的xml文件
    			Document document = reader.read(file);
    			//获得document中的根节点
    			Element rootElement = document.getRootElement();
    			//获得根节点下面所有的子节点
    			List<Element> elements = rootElement.elements();
    			//遍历elements集合,拿到每一个子节点
    			for(Element e:elements){
    				//获得元素的名字和文本值
    				String s = e.attributeValue("id");
    				System.out.println(e.getName()+"节点的id属性的值为:"+s);
    				
    				//获得当前这个子节点下面所有的子节点
    				List<Element> elements2 = e.elements();
    				//遍历elements2集合,拿到每一个子节点
    				for(Element e2:elements2){
    					System.out.println(e2.getName()+" : "+e2.getText());
    				}
    				
    			}
    			
    		} catch (Exception e) {
    			e.printStackTrace();
    		}
    		
    	}
    	
    	public static void main(String[] args) {
    		Dom4jTest t = new Dom4jTest();
    		String filePath = "src/XMLjiexi/app.xml";
    		t.createDom(filePath);
    	//    t.readXML(filePath);
    	}
    
    
    
    }
    

      修改一个xml文件,需要下载相应的jar包

    package XMLjiexi;
    
    import java.io.File;
    import java.io.FileWriter;
    import java.io.IOException;
    import java.util.Iterator;
    import java.util.List;
    
    import org.dom4j.Attribute;
    import org.dom4j.Document;
    import org.dom4j.DocumentException;
    import org.dom4j.io.SAXReader;
    import org.dom4j.io.XMLWriter;
    
    public class Dom4jUpdate {
    	public void modifyXML(File filePath) {
    		try {
    			SAXReader reader = new SAXReader();
    			Document document = reader.read(filePath);
    			//System.out.println("nihao");
    			//定位节点需要用到一个jar包:jaxen-1.1-beta-6.jar
    			List list = document.selectNodes("//city/@name");
    			//System.out.println("nihaomingtian");
    			Iterator iter = list.iterator();
    			while(iter.hasNext()) {
    				Attribute att = (Attribute)iter.next();
    				if(att.getValue().equals("上海")) {
    					att.setValue("成都");
    				}
    			}
    		XMLWriter output=new XMLWriter(new FileWriter(new File("C:/xml/app-modify.xml")));	
    		} catch (DocumentException e) {
    			System.out.println(e.getMessage());
    		} catch (IOException e) {
    			System.out.println(e.getMessage());
    		}
    	}
    	public static void main(String[] args) {
    		Dom4jUpdate update = new Dom4jUpdate();
    		update.modifyXML(new File("C:/Users/YF/eclipse-workspace-javaee/XML/src/XMLjiexi/app.xml"));
    		
    	}
    }
    

      

     

  • 相关阅读:
    django学习----http协议
    线程进程和协程
    内置函数
    我所了解的递归
    函数的闭包和装饰器
    字符串的内置方法
    格式化输入输出
    逻辑运算符和操作运算符
    python流程控制
    计算机网络原理
  • 原文地址:https://www.cnblogs.com/yfstudy/p/9183553.html
Copyright © 2011-2022 走看看