读取XML的几种方式

一、为什么使用XML

1、便于不同应用程序之间通信。

2、便于不同平台之间通信。

3、便于不同平台之间数据共享。

二、Dom读取

xml文件内容

<?xml version="1.0" encoding="UTF-8"?>
<bookstore>
	<book id="1">
		<name>冰与火之歌</name>
		<author>乔治马丁</author>
		<year>2014</year>
		<price>89</price>
	</book>
	<book id="2">
		<name>安徒生童话</name>
		<year>2004</year>
		<price>77</price>
		<language>English</language>
	</book>
</bookstore>

dom代码

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

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

public class DomReadXml {

	public static void main(String[] args) {
		readXml();
	}

	public static void readXml() {
		try {
			// 创建解析器工厂
			DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
			DocumentBuilder db = factory.newDocumentBuilder();
			// 创建一个Document对象
			Document doc = db.parse("books.xml");
			NodeList bookList = doc.getElementsByTagName("book");
			// 获取节点个数
			System.out.println("一共有" + bookList.getLength() + "本书");

			// 遍历每个book节点
			for (int i = 0; i < bookList.getLength(); i++) {
				System.out.println("*******************************");
				// 索引从零开始
				org.w3c.dom.Node book = bookList.item(i);
				// 获取book节点所有属性集合
				org.w3c.dom.NamedNodeMap attrs = book.getAttributes();

				System.out.println("第" + (i + 1) + "本书共有" + attrs.getLength() + "属性");
				// 遍历book属性,不知道节点属性和属性名情况
				for (int j = 0; j < attrs.getLength(); j++) {
					// 获取某一个属性
					org.w3c.dom.Node attr = attrs.item(j);
					System.out.print("属性名:" + attr.getNodeName());
					System.out.println(" --- 属性值:" + attr.getNodeValue());
				}

				// 若已经知道book节点有且只有1个ID属性,可用以下方式
				// org.w3c.dom.Element e = (org.w3c.dom.Element)
				// bookList.item(i);
				// System.out.println("Element属性值:"+e.getAttribute("id"));

				NodeList childNodes = book.getChildNodes();
				for (int k = 0; k < childNodes.getLength(); k++) {
					// 区分,去掉空格和换行符
					if (childNodes.item(k).getNodeType() == Node.ELEMENT_NODE) {
						// 获取element类型的节点和节点值
						System.out.print("节点名:" + childNodes.item(k).getNodeName());
						System.out.print(" --- 节点值:" + childNodes.item(k).getFirstChild().getNodeValue());
						System.out.println(" --- 节点值:"+childNodes.item(k).getTextContent());
					}
				}
			}

		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

结果输出:

三、Dom4j读取

使用dom4j需要导入相关的jar包

import java.io.File;
import java.util.Iterator;
import java.util.List;

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

public class Dom4jReadXml {

	public static void main(String[] args) {
		readXml();
	}

	public static void readXml(){
		try {
			// 创建SAXReader对象
			SAXReader reader = new SAXReader();
			// 加载xml文件
			Document dc= reader.read(new File("books.xml"));
			// 获取根节点
			Element e = dc.getRootElement();
			// 获取迭代器
			Iterator it = e.elementIterator();
			// 遍历迭代器,获取根节点信息
			while(it.hasNext()){
				Element book = (Element) it.next();
				
				List<Attribute>  atts= book.attributes();
				// 获取book属性名和属性值
				for (Attribute att : atts) {
					System.out.println("节点名:"+att.getName()+"节点值:"+att.getValue());					
				}
				
				Iterator itt = book.elementIterator();
				while(itt.hasNext()){
					Element b = (Element) itt.next();
					
					System.out.println("属性名:"+b.getName()+"属性值:"+b.getText());
				}
				
			}
		} catch (Exception e) {
			// TODO: handle exception
		}
	}
	

}

结果输出:

四、JDom读取

使用jdom需要导入相关的jar包

import java.io.FileInputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;

import org.jdom.Attribute;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.input.SAXBuilder;

public class JDomReadXml {
	
	public static void main(String[] args) {
		// 
		readXml();
	}

	@SuppressWarnings("unchecked")
	public static void readXml(){
		List<Book> bList = new ArrayList<Book>();
		try {
			// 创建一个SAXBuilder对象
			SAXBuilder builder = new SAXBuilder();
			// 创建一个输入流
			InputStream in = new FileInputStream("books.xml");
			
			// 处理乱码情况
			InputStreamReader isr = new InputStreamReader(in, "UTF-8");
			
			// 通过build方法,将输入流加载到SAXBuilder中
			Document doc = builder.build(isr);
			// 通过Document对象获取根节点
			Element foo= doc.getRootElement();
			// 获取根节点下子节点名
			List<Element> allChildren = foo.getChildren();
			// 进行解析
			for (Element book : allChildren) {
				
				Book b = new Book();
				
				System.out.println("开始解析第"+(allChildren.indexOf(book)+1)+"本书");
				// 解析book属性集合
				List<Attribute> attrList = book.getAttributes();
				// 遍历(针对不清楚节点下属性名)
				for (Attribute attr : attrList) {
					System.out.println("属性名:"+attr.getName() +" -- 属性值:"+attr.getValue());
					if("id".equals(attr.getName())){
						b.setId(attr.getValue());
					}
				}
				
				// 清楚知道属性名获取属性值
				String v = book.getAttributeValue("id");
				System.out.println("清楚知道属性名"+v);
				
				// 对book节点子节点的节点名和节点值进行遍历
				List<Element> bookChiles = book.getChildren();
				for (Element element : bookChiles) {
					System.out.println("属性名:"+element.getName() +" -- 属性值:"+element.getValue());
					
					if("name".equals(element.getName())){
						b.setName(element.getValue());
					}else if("author".equals(element.getName())){
						b.setAuthor(element.getValue());
					}else if("year".equals(element.getName())){
						b.setYear(element.getValue());
					}else if("price".equals(element.getName())){
						b.setPrice(element.getValue());
					}else if("language".equals(element.getName())){
						b.setLanguage(element.getValue());
					}
				}
				System.out.println("结束解析第"+(allChildren.indexOf(book)+1)+"本书");
				bList.add(b);
				b = null;
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

结果输出:

五、Sax读取

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

public class SaxReadXml {
	
	public static void main(String[] args) {
		readXml();
	}
	
	public static void readXml() {
		try {
			// 创建工厂
			SAXParserFactory sf=SAXParserFactory.newInstance();
			// 获取SAXParser实例
			SAXParser sp = sf.newSAXParser();
			// 创建一个解析对象
			SAXParserHandler handler = new SAXParserHandler();
			sp.parse("books.xml", handler);
			
			for(Book book : handler.getbList()){
				System.out.println(book.getId());
				System.out.println(book.getName());
				System.out.println(book.getAuthor());
				System.out.println(book.getYear());
				System.out.println(book.getPrice());
				System.out.println(book.getLanguage());
				System.out.println("*****************");
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

SAXParserHandler .java

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

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

public class SAXParserHandler extends DefaultHandler {

	int bookIndex = 0;
	String str = null;
	Book b = null;
	private List<Book> bList = new ArrayList<Book>();
	
	public List<Book> getbList() {
		return bList;
	}

	/**
	 * 用来遍历xml文件的开始标签
	 */
	@Override
	public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
		// 调用DefaultHandler的startElement方法
		super.startElement(uri, localName, qName, attributes);
		// 开始解析book元素属性
		if(qName.equals("book")){
			bookIndex++;
			
			// 创建一个book对象
			b = new Book();
			System.out.println("****开始第"+bookIndex+"本书内容****");
			// 已知book元素下属性名称,根据属性名称获取属性值s
			String value = attributes.getValue("id");
			System.out.println("book的属性值是:"+value);
			
			int num = attributes.getLength();
			
			for(int i=0;i<num;i++){
				System.out.print("book元素的第"+(i+1)+"个属性名是:"+attributes.getQName(i));
				System.out.println(" -- 属性值是:"+attributes.getValue(i));
				if(attributes.getQName(i).equals("id")){
					b.setId(attributes.getQName(i));
				}
			}
		}else if(!qName.equals("book") && !qName.equals("bookstore")){
			System.out.print("节点名是:"+qName);
			
		}
	}

	/**
	 * 用来遍历xml文件的结束标签
	 */
	@Override
	public void endElement(String uri, String localName, String qName) throws SAXException {
		// 调用DefaultHandler的endElement方法
		super.endElement(uri, localName, qName);
		// 判断是否针对一本书已经遍历结束
		if(qName.equals("book")){
			bList.add(b);
			b = null;
			System.out.println("****结束第"+bookIndex+"本书内容****");
		}else if(qName.equals("name")){
			b.setName(str);
		}else if(qName.equals("author")){
			b.setAuthor(str);
		}else if(qName.equals("year")){
			b.setYear(str);
		}else if(qName.equals("price")){
			b.setPrice(str);
		}else if(qName.equals("language")){
			b.setLanguage(str);
		}
	}
	
	/**
	 * 用来标志解析开始
	 */
	@Override
	public void startDocument() throws SAXException {
		// 调用DefaultHandler的startDocument方法
		super.startDocument();
		System.out.println("解析开始");
	}
	
	/**
	 * 用来标志解析结束
	 */
	@Override
	public void endDocument() throws SAXException {
		// 调用DefaultHandler的endDocument方法
		super.endDocument();
		System.out.println("解析结束");
	}
	
	/**
	 * 用来标志解析结束
	 */
	@Override
	public void characters(char[] ch, int start, int length) throws SAXException {
		// 调用DefaultHandler的characters方法 
		super.characters(ch, start, length);
		str = new String(ch, start, length);
		if(!str.trim().equals("")){
			System.out.println(" -- 节点值是:"+str);
		}		
	}
	
}

结果输出:

六、附赠properties的读取

在src文件中新建文件dataBase.properties

在文件中写入projectName=\u6D4B\u8BD5\u9879\u76EE

public class ReadProperties {

	public static void main(String[] args){
		System.out.println(getProjectName());
	}
	
	public static String getProjectName() {
		Properties pro = new Properties();
		try {
			// 获取文件内容
			InputStream cp = ReadProperties.class.getResourceAsStream("/dataBase.properties");
			// 加载
			pro.load(cp);
			// 获取projectName属性
			return pro.getProperty("projectName");
		} catch (Exception e) {
			e.printStackTrace();
			return "出错了";
		}
	}
}

结果输出:测试项目

七、总结

 * dom平台无关,官方解析方式,一次性加载,方便解析,代码容易编写,当文件过大,容易造成内存溢出
 * sax基于事件驱动的解析方式,加载时进行验证判断,内存耗费小,不易编码,很难同时访问一个xml中的多处不同数据
 * 
 * jdom和dom4j是基于sax扩展
 * 
 * jdom仅使用具体类而不使用接口,api中大量使用了collections类
 * 
 * dom4j是jdom的一种智能分支,具有性能优异,灵活性好,功能强大和易使用的特点
相关推荐
天使day几秒前
Maven
java·maven
汇匠源3 分钟前
共享无人系统,从出行到生活全面覆盖
java·生活
小灰灰要减肥1 小时前
装饰者模式
java
张铁铁是个小胖子1 小时前
MyBatis学习
java·学习·mybatis
Yan.love2 小时前
开发场景中Java 集合的最佳选择
java·数据结构·链表
椰椰椰耶2 小时前
【文档搜索引擎】搜索模块的完整实现
java·搜索引擎
大G哥2 小时前
java提高正则处理效率
java·开发语言
智慧老师2 小时前
Spring基础分析13-Spring Security框架
java·后端·spring
lxyzcm2 小时前
C++23新特性解析:[[assume]]属性
java·c++·spring boot·c++23
V+zmm101343 小时前
基于微信小程序的乡村政务服务系统springboot+论文源码调试讲解
java·微信小程序·小程序·毕业设计·ssm