Java自带的XML解析

JAXP (Java API for XML Processing,意为处理XML的Java API)

解析XML一般有两种方式:

一种是DOM方式:一次性读取XML内容存入内存

优点:能进行各种增删改查的操作

确定:占用内存大

使用:给定需要读取的文件即可读取,读取出来之后再根据自己写的方法进行操作

还有一种是SAX方式:顺序读取内容,碰到什么样的标签执行什么样的操作由自己定义

优点:占用内存小

缺点:不能进行各种增删改查操作,只能遍历出内容

使用:给定需要读取的文件和一个操作集,操作集会指示在遍历的时候遇到什么冻死做什么事

对xml进行操作就是操作xml文件当中的元素和属性:<元素 属性='属性值'>文本内容

由于元素里面的文本内容可以是子元素,而为了阅读方便通常都是换行另起一行并缩进的,造成了父元素和子元素之间有两段空格和一个换行,解析xml文档的时候识别不了,所以也会一并读取出来

举例:

XML文件:students.xml


 
 		
 			tom
 			20
 			male
 			
 		
 			jerry
 			19
 			female
 				   
 

DOM方式实现类:DomDemo.java

package com.jyh.xml.parser;

import java.io.File;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

public class DomDemo {
	public static void main(String[] args) {
		//1.获取jaxp工厂
		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
		try {
			//2.获取解析器
			DocumentBuilder builder = factory.newDocumentBuilder();
			//3.用解析器加载xml文档--->Document
			Document document = builder.parse(new File("src/students.xml"));
			//4.获得所有学生集合
			NodeList studentList = document.getElementsByTagName("student");
			//5.遍历学生集合
			for(int i = 0; i < studentList.getLength(); i ++){
				//通过下标获得各个学生
				Element stuElm = (Element)studentList.item(i);
				//获取每个学生的学号属性
				String number = stuElm.getAttribute("number");
				System.out.println("学号:" + number);
				//获取每个学生下的所有子节点(包括空白)
				NodeList childrenList = stuElm.getChildNodes();
				//便利子节点集合获取元素
				int length = childrenList.getLength();
				for(int j = 0; j < length; j ++){
					Node node = childrenList.item(j);
					//判断子节点是不是element元素类型(因为遍历过程中会遍历出空格和换行)
					if(node.getNodeType() == Node.ELEMENT_NODE){
						Element child = (Element) node;
						switch (child.getNodeName()) {
						case "name":
							String name = child.getTextContent();
							System.out.println("姓名:" + name);
							break;
						case "age":
							String age = child.getTextContent();
							System.out.println("年龄:" + age);
							break;
						case "sex":
							String sex = child.getTextContent();
							System.out.println("性别:" + sex);
							break;
						default:
							break;
						}
					}
					
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}



这种方式就是对树进行操作,开始根据根元素名获取根元素集合:
NodeList studentList = document.getElementsByTagName("student");
然后遍历根集合获得每个根元素,由于有了根元素,所以可以根据根节点获取下面的子元素:
NodeList childrenList = stuElm.getChildNodes();
获得属性就用方法
String number = stuElm.getAttribute("number");


输出结果:
学号:jyh_0001
姓名:tom
年龄:20
性别:male
学号:jyh_0002
姓名:jerry
年龄:19
性别:female

SAX方式实现类:SaxDemo.java和MyHandle.java
SaxDemo.java:

package com.jyh.xml.parser;

import java.io.File;

import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;


public class SaxDemo {
	public static void main(String[] args) {
		//1.获得解析器工厂
		SAXParserFactory factory = SAXParserFactory.newInstance();
		//2.获得解析器
		try {
			SAXParser parser = factory.newSAXParser();
			//3.解析文档(告诉去读取哪个文档,读取文档过程中遇到什么情况该怎么处理)
			//第一个参数代表要解析的文档,第二个参数代表解析文档过程中遇到什么样的情况该怎么做
			parser.parse(new File("src/students.xml"), new MyHandle());
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}


 MyHandle.java:

package com.jyh.xml.parser;

import org.xml.sax.helpers.DefaultHandler;

public class MyHandle extends DefaultHandler{

	//文档开始解析
	@Override
	public void startDocument() throws org.xml.sax.SAXException {
		System.out.println("文档开始解析");
	}

	/*遇到元素开始解析
	 * 参数3是读取到的元素名称,参数4是读取到的元素的属性集
	 */
	@Override
	public void startElement(String uri, String localName, String qName,
			org.xml.sax.Attributes attributes) throws org.xml.sax.SAXException {
		System.out.println(qName + "元素开始解析");
		//判断遇到的是不是学生元素
		if(qName.equals("student")){
			//如果是则获取该元素的属性
			String number = attributes.getValue("number");
			System.out.println("学号:" + number);
		}
	}
	
	//遇到文本开始解析
	@Override
	public void characters(char[] ch, int start, int length)
			throws org.xml.sax.SAXException {
		String str = new String(ch,start,length);
		str = str.trim();
		if(str.length() > 0){
			System.out.println(str);
		}
	}
	
	//元素解析结束
	@Override
	public void endElement(String uri, String localName, String qName)
			throws org.xml.sax.SAXException {
		System.out.println(qName + "元素解析结束");
	}

	//文档结束触发
	@Override
	public void endDocument() throws org.xml.sax.SAXException {
		System.out.println("文档解析结束");
	}
	
}

MyHandle里有五个方法:
startDocument();-->开始解析文档
startElement(String uri, String localName, String qName,org.xml.sax.Attributes attributes);-->碰到元素开始符则开始解析元素
String number = attributes.getValue("number");-->获取元素的属性
characters(char[] ch, int start, int length);-->碰到文本开始解析文本
endElement();-->碰到元素结束符,结束元素解析
endDocument(String uri, String localName, String qName);-->结束解析文档


输出结果(优化之后):
文档开始解析
students元素开始解析
student元素开始解析
学号:jyh_0001
name元素开始解析
tom
name元素解析结束
age元素开始解析
20
age元素解析结束
sex元素开始解析
male
sex元素解析结束
student元素解析结束
student元素开始解析
学号:jyh_0002
name元素开始解析
jerry
name元素解析结束
age元素开始解析
19
age元素解析结束
sex元素开始解析
female
sex元素解析结束
student元素解析结束
students元素解析结束
文档解析结束

你可能感兴趣的:(java)