万字暴力详解XML内容及其三种解析方式

本文详细介绍了XML的三种主要解析方式DOM、SAX和dom4j的使用,包括它们各自的特点、解析过程和示例。DOM适合处理小文件,SAX逐行读取并解析,而dom4j推荐用于XML文档的快速读取和操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

xml

XML作用

1.数据传输,不同语言不同机器都可以相互传输
2.配置文件
3.数据存储数据量要小

XML语法

dom解析
1.加载全部xml内容
2.生成Document对象
3.所有标签元素**对象都在对应Document对象里面获取

数据量小的文件用dom

SAX解析(事件解析)
1.读取一个开始标签就开始解析,读一点解析一点,读到文本内容就解析文本内容,读到结束标签
就解析结束标签
2.读开始标签,文本内容,结束标签都会自动调用指定的对应方法

xml三种解析方式的过程

DOM解析(原生)
步骤
1.创建工厂对象
	DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
2.创建解析对象
	DocumentBuilder builder = factory.newDocumentBuilder();
3.调用解析方法解析xml文件
		File f=new File("src/com/briup/jaxp/students.xml");
		org.w3c.dom.Document document = builder.parse(f);

		NodeList list = document.getElementsByTagName("stu");
		List<Student> stus=new ArrayList<Student>();
4.list包含了所有的stu节点对象
5.循环遍历List集合 每次都创建一个student对象 并对对象进行遍历(根节点内子节点的每一个对象)
    Element node=(Element) list.item(i);     //标签内的属性(根节点子节点的标签属性)
	int  id =Integer.parseInt(node.getAttribute("id")) ;
	int  money =Integer.parseInt(node.getAttribute("money")) ;
	stu.setId(id);    
	stu.setMoney(money);
	//内层循环中属性(每个子节点的子节点名属性的检索赋值)
	NodeList childList = node.getChildNodes();
	获取节点类型去除文本	
        if (item.getNodeType()==Node.ELEMENT_NODE) {   //此处Node.ELEMENT_NODE可为1
					//获取该节点名字
					String nodeName=item.getNodeName();
					//获取文本内容
					String nodeValue =item.getFirstChild().getNodeValue();
					switch (nodeName) {
					case "name":
						stu.setName(nodeValue);
						break;
					case "age":
						stu.setAge(Integer.parseInt(nodeValue));
						break;
					case "gender":
						stu.setGender(nodeValue);
						break;
					case "like":
						stu.setLike(nodeValue);
						break;
					
					default:
						break;
					}
					
				}
	什么类型属性的节点就赋予相应的值,
6.外层for循环外添加对象到集合中
7.遍历该集合,检查解析过程是否正确

示例:

xml

<?xml version="1.0" encoding="utf-8"?>
<students>
	<stu id="1" money="1000">
	<name>胡歌</name>
	<age>20</age>
	<gender></gender>
	<like>学习</like>
	</stu>
	<stu id="2" money="1500">
	<name>赵丽颖</name>
	<age>30</age>
	<gender></gender>
	<like>小刀</like>
	</stu>
	<stu id="3" money="2000">
	<name>马超</name>
	<age>30</age>
	<gender></gender>
	<like></like>
	</stu>
	<stu id="4" money="1300">
	<name>孙红雷</name>
	<age>40</age>
	<gender></gender>
	<like>西瓜</like>
	</stu>
</students>
package com.briup.jaxp;

import java.io.File;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import javax.swing.text.Document;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.soap.Node;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

/**
* @author yxqiang
* @version 创建时间:2021年9月7日上午10:05:16
*/
public class StudentDom {
public static void main(String[] args) {
	try {
		//1.创建工厂类对象
		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
		
		//2.创建解析对象
		DocumentBuilder builder = factory.newDocumentBuilder();
		
		//3.调用解析方法解析xml文件
		File f=new File("src/com/briup/jaxp/students.xml");
		org.w3c.dom.Document document = builder.parse(f);
		//list包含了所有的stu节点对象
		NodeList list = document.getElementsByTagName("stu");
		List<Student> stus=new ArrayList<Student>();
		for (int i = 0; i < list.getLength();i++) {
			Student stu=new Student();
			Element node=(Element) list.item(i);
			//获取属性内容
			int  id =Integer.parseInt(node.getAttribute("id")) ;
			int  money =Integer.parseInt(node.getAttribute("money")) ;
//			System.out.println(id+":"+money);
			stu.setId(id);
			stu.setMoney(money);
			NodeList childList = node.getChildNodes();
			for (int j = 0; j < childList.getLength(); j++) {
				org.w3c.dom.Node item = childList.item(j);
				//获取当前节点类型,去除文本内容
				if (item.getNodeType()==Node.ELEMENT_NODE) {   //此处Node.ELEMENT_NODE可为1
					//获取该节点名字
					String nodeName=item.getNodeName();
					//获取文本内容
					String nodeValue =item.getFirstChild().getNodeValue();
					switch (nodeName) {
					case "name":
						stu.setName(nodeValue);
						break;
					case "age":
						stu.setAge(Integer.parseInt(nodeValue));
						break;
					case "gender":
						stu.setGender(nodeValue);
						break;
					case "like":
						stu.setLike(nodeValue);
						break;
					
					default:
						break;
					}
					
				}
			}
			stus.add(stu);
		}
		//验证
		for (Student student : stus) {
			System.out.println(student);
		}
	} catch (ParserConfigurationException | SAXException | IOException e) {
		// TODO 自动生成的 catch 块
		e.printStackTrace();
	}
}
}

//解析结果
Student [id=1, money=1000, name=胡歌, age=20, gender=, like=学习]
Student [id=2, money=1500, name=赵丽颖, age=30, gender=, like=小刀]
Student [id=3, money=2000, name=马超, age=30, gender=, like=]
Student [id=4, money=1300, name=孙红雷, age=40, gender=, like=西瓜]

SAX解析(原生)
步骤
1.获取SAX解析工厂类对象SAXParserFactory factory= SAXParserFactory.newInstance();
2.获取SAX对应的解析器对象 SAXParser parser=factory.newSAXParser();
3.解析文件 File f =new File()对象 传入要解析的文件路径  parser.parse(f, dh);
4.新建静态StudentHander类继承DefaultHandler 重写里面五个方法
5.最后返回一个List集合

示例:

<?xml version="1.0" encoding="utf-8"?>
<students>
	<stu id="1" money="1000">
	<name>胡歌</name>
	<age>20</age>
	<gender></gender>
	<like>学习</like>
	</stu>
	<stu id="2" money="1500">
	<name>赵丽颖</name>
	<age>30</age>
	<gender></gender>
	<like>小刀</like>
	</stu>
	<stu id="3" money="2000">
	<name>马超</name>
	<age>30</age>
	<gender></gender>
	<like></like>
	</stu>
	<stu id="4" money="1300">
	<name>孙红雷</name>
	<age>40</age>
	<gender></gender>
	<like>西瓜</like>
	</stu>
</students>
package com.briup.jaxp;

import java.io.File;

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.omg.PortableServer.ID_ASSIGNMENT_POLICY_ID;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

/**
* @author yxqiang
* @version 创建时间:2021年9月7日上午11:01:35
*/
public class StudentSax {
public static void main(String[] args) {
	try {
		//1.获取SAX解析的工厂类对象
		SAXParserFactory factory = SAXParserFactory.newInstance();
		
		//2.获取SAX对应的解析器对象
		SAXParser parser = factory.newSAXParser();
		
		//3.解析
		File f=new File("src/com/briup/jaxp/students.xml");
		StudentHandler dh=new StudentHandler();
		parser.parse(f, dh);
		//验证
		List<Student> list =dh.getList();
		for (Student student : list) {
			System.out.println(student);
		}
		
	} catch (ParserConfigurationException e) {
		// TODO 自动生成的 catch 块
		e.printStackTrace();
	} catch (SAXException e) {
		// TODO 自动生成的 catch 块
		e.printStackTrace();
	} catch (IOException e) {
		// TODO 自动生成的 catch 块
		e.printStackTrace();
	}
	
}
public static class StudentHandler extends DefaultHandler{
	private Student stu;
	private List<Student> list;
	private String tagName; //当前标签名
//文档解析开始
	@Override
	public void startDocument() throws SAXException {
	 list=new ArrayList<Student>();
	}

//读取开始元素
	/*
	 * uri:文件路径
	 * localName :命名空间
	 * qName:开始标签名
	 * attributes:开始标签的属性
	 */
	@Override
	public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
		if ("stu".equals(qName)) {
			stu=new Student();
			int id=Integer.parseInt(attributes.getValue("id"));
			int money=Integer.parseInt(attributes.getValue("money"));
//			System.out.println(id+":"+money);
			stu.setId(id);
			stu.setMoney(money);
		}else {
			tagName=qName;
		}
	}
	
	
//获取文本元素
	@Override
	public void characters(char[] ch, int start, int length) throws SAXException {
		String str=new String(ch,start,length);
		str.trim();   //该方法去掉前后空格   中间的不能去掉
		if("name".equals(tagName)) {
			stu.setName(str);
		}else if ("age".equals(tagName)) {
			stu.setAge(Integer.parseInt(str));
		}else if ("gender".equals(tagName)) {
			stu.setGender(str);
		}else if ("like".equals(tagName)) {
			stu.setLike(str);
		}
	}
//读取结束标签
	/*
	 * uri:文件路径
	 * localName :命名空间
	 * qName:结束标签名
	 */
	@Override
	public void endElement(String uri, String localName, String qName) throws SAXException {
	if ("stu".equals(qName)) {
		list.add(stu);
	}
	tagName=null;   //没有读取到标签的时候放止读取文字
	}
//文档结束
	@Override
	public void endDocument() throws SAXException {
		//不需要操作
	}
	public List<Student> getList(){
		return list;
	}
}
}




//解析结果
Student [id=1, money=1000, name=胡歌, age=20, gender=, like=学习]
Student [id=2, money=1500, name=赵丽颖, age=30, gender=, like=小刀]
Student [id=3, money=2000, name=马超, age=30, gender=, like=]
Student [id=4, money=1300, name=孙红雷, age=40, gender=, like=西瓜]


dom4j解析(推荐)
步骤
1.导入dom4j.jar包
2.创建解析器对象
	SAXReader saxReader = new SAXReader();
3.File file =new File()传入要解析的xml路径
4.掉用saxReader的read(file)方法传入file路径 获取返回值Document document
5.获取根节点元素
	Element rootElement = document.getRootElement();
6.teacher元素对象集合
	List<Element> elements = rootElement.elements(); //根节点元素.elements返回集合元素对象
7.再创建List集合list用于存放teacher对象
8.增强for循环遍历elements集合
	8.1创建teacher对象
	8.2获取对象节点的属性存放一个集合中
	8.3将获取到的属性值赋值给相应的对象属性(teacher中只有id)//t.setId(Integer.parseInt(a.getValue()));	
	8.4获取对象节点子节点的内容根据标签名赋值可以用if(nodename.equals("..."))或者用Switch最好;
	8.5获取文本内容用子节点.getText()赋值给对象
9.添加对象到集合中
10.返回集合用于检查
	
	

示例:

xml

<?xml version="1.0" encoding="utf-8"?>
<teachers>
<tea id ="1">
<name>张三</name>
<age>30</age>
<salary>5000</salary>
</tea>
<tea id ="2">
<name>李四</name>
<age>30</age>
<salary>8000</salary>
</tea>
<tea id ="3">
<name>王五</name>
<age>28</age>
<salary>4300</salary>
</tea>
</teachers>
package com.briup.jaxp;

import java.io.File;

import java.util.ArrayList;
import java.util.List;

import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

/**
* @author yxqiang
* @version 创建时间:2021年9月7日下午2:19:09
*/
public class Dom4jTest {
	public static void main(String[] args) {
		try {
			//创建解析器对象
			SAXReader saxReader = new SAXReader();
			File file=new File("src/com/briup/jaxp/teacher.xml");
			Document document = saxReader.read(file);
			//获取根节点元素
			Element rootElement = document.getRootElement();
//			System.out.println(rootElement.getName());
			//teacher元素对象集合
			List<Element> elements = rootElement.elements();
			
			List<Teacher> list=new ArrayList<Teacher>();  //存放老师的对象
			for (Element tea : elements) {
				Teacher t=new Teacher();
				List<Attribute> attributes = tea.attributes();
				//循环属性
				for (Attribute a : attributes) {
					t.setId(Integer.parseInt(a.getValue()));	
				}
				//获取每一个tea的子节点
				List<Element> nodeElements = tea.elements();
				for (Element el : nodeElements) {
					String nodename = el.getName();
					if (nodename.equals("name")) {
						//获取文本内容
						t.setName(el.getText());
					}else if (nodename.equals("age")) {
						
						t.setAge(Integer.parseInt(el.getText()));
					}else if (nodename.equals("salary")) {
						t.setSalary(Double.parseDouble(el.getText()));
					}
				}
				list.add(t);
			}
			for (Teacher teacher : list) {
				System.out.println(teacher);
			}
			
		} catch (DocumentException e) {
			// TODO 自动生成的 catch 块
			e.printStackTrace();
		}
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值