javaweb基础之xml的三种解析方式

一、dom4j  解析

  1、1 什么是Dom4j

  dom4j  是一个java的XML API,是jdom的升级品,用来读写XML文件的。dom4j 是一个十分优秀的JavaXML API, 具有性能优异、功能强大和极其使用的特点, 它的性能超过sun公司官方的dom技术,同时它也是一个开源的软件,可以再SourceForge上找到

 1、2 核心类

SAXReader Dom4J的读取文件的类   read 读取指定的xml文件

Document 文档类 用于加载指定的文档   常用方法:getRootElement 获取根节点 

Element 标签类,元素  ​ 常用方法:

  • ​ elements 获取所有的直接子标签
  • ​ attribute 获取指定属性名称的属性对象
  • ​ elementText 获取指定子标签名称的文本内容
  • ​ element 获取指定标签名称的标签对象
  • ​ getText(); 得到当前标签中间的文本

1、3  dom4j 实现XML解析

 index.xml

<?xml version="1.0" encoding="UTF-8"?>
<books>
	<book id="1001" publishDate="2017-9-10">
		<name>java入门</name>
		<author>小胖</author>
		<price>0.1</price>
	</book>
	<book id="1002" publishDate="2018-3-23">
		<name>数据库</name>
		<author>小糖</author>
		<price>83</price>
	</book>
</books>

XmlParse_elementText.java

 导的jar包是 import org.dom4j.*;下的

public static void main(String[] args) throws Exception {
		         //解析xml
				//1、创建SAXReader对象
				SAXReader saxReader=new SAXReader();
				//2、获得Document对象
				Document document=saxReader.read(new File("index.xml"));
				//3获得根节点
				Element element = document.getRootElement();
				//4、得到根节点的子节点列表
				List<Element> list = element.elements();
				     List<Book> books = new ArrayList<>();
				     for(Element ele: list){
				    	 //获取一个属性    attribute(0);    attribute("id");
				    	  Attribute a1 = ele.attribute(0);
				    	   Attribute a2 = ele.attribute(1);
 				         Book book = new Book();
 				         book.setId(Integer.parseInt(a1.getValue()));
				         book.setPublishDate(a2.getValue());
				     book.setName(ele.elementText("name"));
				     book.setPrice(Double.parseDouble(ele.elementText("price")));
				    book.setAuthor(ele.elementText("author"));
				     books.add(book);
				     }			     
				System.out.println(books);     
				
		  }

二、SAX解析

2、1 什么是SAX

SAX,全称Simple API for XML,既是一种接口,也是一种软件包。它是一种XML解析的替代方法。SAX不同于DOM解析,它逐行扫描文档,一边扫描一边解析。由于应用程序只是在读取数据时检查数据,因此不需要将数据存储在内存中,这对于大型文档的解析是个巨大优势

dom:把xml文件读取到内容,构建树形结构

2、2 SAX优缺点

  • SAX的优点:

    1. 解析速度快

    2. 占用内存少

  • SAX的缺点:

    1. 无法知道当前解析标签(节点)的上层标签,及其嵌套结构,仅仅知道当前解析的标签的名字和属性,要知道其他信息需要程序猿自己编码

    2. 只能读取XML,无法修改XML

    3. 无法随机访问某个标签(节点)

  • SAX解析适用场合 

    SAX解析适用场合 对于CPU资源宝贵的设备,如Android等移动设备对于只需从xml读取信息而无需修改xml

2、3代码的实现

创建自定义处理数据的模板类,继承DefaultHandler类

重新四个方法

  • startDocument();解析到xml文件的开始
  • startElement();解析到标签的开头 <book>
  • endElement(); 解析到标签结尾</book>
  • endDocument();解析到xml文件的结束
  • character(); 解析到标签中间的文本

导的主要java包为 ; org.xml.sax下的 和 javax.xml.parsers下的

SaxParser.java

   public static void main(String[] args) throws Exception {
		//创建SAXParserFactory对象
		SAXParserFactory factory = SAXParserFactory.newInstance();
		//创建SAXParser对象
		SAXParser saxParser = factory.newSAXParser();
		//创建处理器模板对象
		MyBookHandler bookHandler = new MyBookHandler();
		//解析xml
		saxParser.parse(new FileInputStream("index.xml"), bookHandler);
		
		//遍历 books
		List<Book> books = bookHandler.getBooks();
		for (Book book: books) {
			System.out.println(book);
		}
		
	}
 

MyBookHandler.java

class MyBookHandler extends DefaultHandler{
    //声明解析后存储对象的集合
	private Book book;
	private List<Book> books;
	private String tagName;
	public List<Book> getBooks(){
		return books;
	}
	@Override
	public void startDocument() throws SAXException {
		System.out.println("文档的开始!!!");	
	}
	/*
	 * 解析到标签的开头
	 * String qname 解析到标签的名称  
	 * Attributes attributes 当前这个标签中的属性
	 * */
	@Override
	public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
		if("books".equals(qName)){
			books = new ArrayList<>();  //解析到books标签的开头执行	
		}else if("book".equals(qName)){
			book =new Book();
			//获取属性
			String ids = attributes.getValue("id");
			String date =attributes.getValue("publishDate"); 
			book.setId(Integer.valueOf(ids));
			book.setPublishDate(date);
			
		}
	   tagName = qName;
	}
	 // 解析到文本

	@Override
	public void characters(char[] ch, int start, int length) throws SAXException {
	     //把char类型的数组---》String
		String content = new String(ch,start,length);
		//有可能得到换行符或者空格
		content = content.replace(" ","");
		//获得标签名称,定义个全局变量 tagName
		if("name".equals(tagName)){
			book.setName(content);
		} else if("author".equals(tagName)){
			book.setAuthor(content);
		}else if("price".equals(tagName)){
			book.setPrice(Double.parseDouble(content));
		}
	}
	
	//解析到标签的结尾
	@Override
	public void endElement(String uri, String localName, String qName) throws SAXException {
	
		//为什么tagName = "";?
		System.out.println(tagName);
		tagName = "";
       		if("book".equals(qName)){
       			books.add(book);
       	}

	}	
	@Override
	public void endDocument() throws SAXException {

		System.out.println("文档的结束!!!");	
	}
}

三、DOM解析

dom解析:xml文件加载到内存中,在内存中构建树形结构,文件比较大,不建议使用DOM解析

  •  DocumentBuilderFactory.newInstance();  创建DocumentBuilderFactory对象
  •   newDocumentBuilder();  创建DocumentBuilder对象
  •   parse("index.xml");  解析文件
  •   getElementsByTagName("books");   解析根节点
  •   item(0);  获得元素
  •   getChildNodes();  获得子节点
  •  getNodeName();   得到节点名称
  •   getAttributes();  获得属性map集合
  •  getNodeValue();  获得节点值
  •  getTextContent();  获得文本内容

3、2 代码实现解析

DOMParser.java

public class DOMParser {
	public static void main(String[] args)  throws Exception{
		//1、创建DocumentBuilderFactory对象
		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
		//2、创建DocumentBuilder对象
		DocumentBuilder documentBuilder = factory.newDocumentBuilder();
		//3、解析xml文件获得Document对象
		Document document = documentBuilder.parse("index.xml");
		//4、开始解析根节点
		NodeList nodeList = document.getElementsByTagName("books");
		//得到books节点
		Node node = nodeList.item(0);
		//得到该节点的子节点
		NodeList bookNodes = node.getChildNodes();
		for(int i=0 ;i<bookNodes.getLength();i++){
			Node n=bookNodes.item(i);
			String tagName = n.getNodeName();
			if("book".equals(tagName)){
				Book book = new Book();
			   //获得属性
				NamedNodeMap namedNodeMap = n.getAttributes();
				//遍历属性集合
				for (int j = 0; j < namedNodeMap.getLength(); j++) {
				Node attribute = namedNodeMap.item(j);
					//获得属性名称
				String attributeName = attribute.getNodeName();
				String attributeValue = attribute.getNodeValue();
				if("id".equals(attributeName)){
					book.setId(Integer.parseInt(attributeValue));
				} else if("publishDate".equals(attributeName)){
					book.setPublishDate(attributeValue);
				}
				}
				//得到book节点的子节点
				NodeList nodeLists= n.getChildNodes();
				for(int k=0 ; k<nodeLists.getLength();k++){
					//得到每个孩子节点
					Node n1 = nodeLists.item(k);
					//获得孩子节点的标签名称
					tagName = n1.getNodeName();
					String value = n1.getTextContent();
				  if("name".equals(tagName)){
					  book.setName(value);
				  }else if("author".equals(tagName)){
					  book.setAuthor(value);
				  }else if("price".equals(tagName)){
					/*  book.setPrice(Double.parseDouble(value));*/
					  book.setPrice(Double.parseDouble(value));
				  }
				}
					System.out.print(book);
			}
			}
		}
	}

猜你喜欢

转载自blog.csdn.net/weixin_42496678/article/details/82084229