Java学习笔记(九):XML文件解析及其工具类制作

一、XML是什么?

XML是指可扩展标记语言(eXtensible MarkupLanguage),它是一种标记语言。它被设计的宗旨是描述数据(XML),而非显示数据(HTML)

应用场景:1、描述数据 2、作为配置文件存在

二、XML语法

在编写XML文档时,需要先使用文档声明来声明XML文档。且必须出现在文档的第一行。
XML声明之前不能有注释 不允许第一行写注释(不同于java)

通常第一句:

<?xml version="1.0" encoding="UTF-8"?>

三、XML的DOM解析

DOM解析原理

XML解析器一次性把整个XML文档加载进内存,然后在内存中构建一颗Document的对象树,通过Document对象,得到树上的节点对象,通过节点对象访问(操作)到XML文档的内容。

给出一个xml文件做为栗子:

<?xml version="1.0" encoding="UTF-8"?>
<students>
<student id="0229" name="柯林" sex="女" birthday="2000/02/29">
	<hobby>刷b站</hobby>
	<hobby>音乐</hobby>
	<hobby>bigbang</hobby>
	<hobby>吃鸡</hobby>
	<introduce>
		喜欢迷幻,后摇,黑泡的短发女孩
	</introduce>
</student>
<student id="0518" name="东永裴" sex="男" birthday="1988/05/18">
	<hobby>跳舞</hobby>
	<hobby>音乐</hobby>
	<hobby>bigbang</hobby>
	<hobby>种花</hobby>
	<introduce>
		宇宙大明星太阳,暖男,笑眼,喜欢狗狗,克里斯马无敌,柯林的爱豆
	</introduce>
</student>
<student id="0818" name="权志龙" sex="男" birthday="1988/08/18">
	<hobby>跳舞</hobby>
	<hobby>音乐</hobby>
	<hobby>bigbang</hobby>
	<hobby>画画</hobby>
	<introduce>
		宇宙大明星龙,权艺术家,小狮子,柯林的爱豆
	</introduce>
</student>
<student id="0406" name="某幻君" sex="男" birthday="1997/04/06">
	<hobby>rap</hobby>
	<hobby>游戏视频</hobby>
	<hobby>给指甲盖打水印</hobby>
	<hobby>剪视频噢</hobby>
	<introduce>
		柯林现实中最想和他做朋友,幽默,头大,脸黑,但是帅呢哈哈,rap无敌的马鸽鸽
	</introduce>
</student>
</students>

从上面的xml文件可以看出 描述的是student,可以给出一个student实体类,以便后续方便使用

package stu.crayue.about_xml.model;

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

/**
* @author Crayue
* @version 2019年11月10日 下午4:46:49
*/
public class StudentInfo {
	private String id;
	private String name;
	private String sex;
	private String birthday;
	private String introduce;
	private List<String> hobbies;
	
	public StudentInfo() {
		hobbies=new ArrayList<String>();
	}

	public String getId() {
		return id;
	}

	public void setId(String id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getSex() {
		return sex;
	}

	public void setSex(String sex) {
		this.sex = sex;
	}

	public String getBirthday() {
		return birthday;
	}

	public void setBirthday(String birthday) {
		this.birthday = birthday;
	}

	public String getIntroduce() {
		return introduce;
	}

	public void setIntroduce(String introduce) {
		this.introduce = introduce;
	}

	public List<String> getHobbies() {
		return hobbies;
	}
	
	public void addHobby(String hobby) {/此处不需要set hobbies的值,重新写一个方法来添加爱好
		if(hobbies.contains(hobby)) {
			return;
		}
		hobbies.add(hobby);
	}

	@Override
	public String toString() {/拼接字符串时,常用stringbuffer
		StringBuffer res= new StringBuffer();
		res.append(id).append(" ")
		.append(sex).append(" ")
		.append(name).append(" ")
		.append(birthday).append("简介:")
		.append(introduce).append("\n");
		for(String hobby:hobbies) {
			res.append('\t').append(hobby).append('\n');
		}
		return res.toString();
	}	
}

现在开始写XML文件的DOM解析吧~

	private static final DocumentBuilderFactory dbf;
	private static DocumentBuilder db;
	
	static {
		dbf=DocumentBuilderFactory.newInstance();	/建立DocumentBuilderFactor,用于获得DocumentBuilder对象:
		try {
			db=dbf.newDocumentBuilder();	/建立DocumentBuidler
		} catch (ParserConfigurationException e) {
			e.printStackTrace();
		}
	}

上面的程序有一个静态代码块;
Java静态代码块中的代码会在类加载JVM时运行,且只被执行一次,也就是说这些代码不需要实例化类就能够被调用。静态块常用来执行类属性的初始化

需要调用parse(InputStream)方法才能打开要处理的XML文档,得到一个Document类的对象;

public static Document getDocument(InputStream is) {
		Document document=null;		/建立Document对象,获取树的入口:
		try {
			document=db.parse(is);
		} catch (SAXException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return document;
	}
public static Document getDocument (String xmlPath) {
		InputStream is = XMLParser.class.getResourceAsStream(xmlPath);
		if(is==null) {
			return null;
		}
		return getDocument(is);
	}

做一个XML解析的工具类,文档里面的内容是未知的,具体的实现需要通过使用此工具的用户完成。因此需要一个抽象的处理方法。

public abstract void dealElement(Element element,int index);	/抽象方法,需要通过用户实现
	
	public void parseTag(Document document,String tagName) {	/获取document中的名为tagname的元素名列表
		NodeList nodeList=document.getElementsByTagName(tagName);
		for(int index=0;index<nodeList.getLength();index++) {
			Element ele = (Element) nodeList.item(index);
			dealElement(ele,index);
		}
	}
	
	public void parseTag(Element element,String tagName) {	/获取element元素里面名为tagname的元素列表
		NodeList nodeList=element.getElementsByTagName(tagName);
		for(int index=0;index<nodeList.getLength();index++) {
			Element ele = (Element) nodeList.item(index);
			dealElement(ele,index);
		}
	}

因此完成了我们的XML解析工具类:源码如下

package stu.crayue.util;
/**
* @author Crayue
* @version 2019年11月10日 下午5:47:17
*/

import java.io.IOException;
import java.io.InputStream;

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

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

public abstract class XMLParser {
	private static final DocumentBuilderFactory dbf;
	private static DocumentBuilder db;
	static {
		dbf=DocumentBuilderFactory.newInstance();
		try {
			db=dbf.newDocumentBuilder();
		} catch (ParserConfigurationException e) {
			e.printStackTrace();
		}
	}

	public XMLParser() {
		
	}
	
	public static Document getDocument (String xmlPath) {
		InputStream is = XMLParser.class.getResourceAsStream(xmlPath);
		if(is==null) {
			return null;
		}
		return getDocument(is);
	}
	public static Document getDocument(InputStream is) {
		
		Document document=null;
		
		try {
			document=db.parse(is);
		} catch (SAXException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return document;
	}
	
	public abstract void dealElement(Element element,int index);
	
	public void parseTag(Document document,String tagName) {
		NodeList nodeList=document.getElementsByTagName(tagName);
		for(int index=0;index<nodeList.getLength();index++) {
			Element ele = (Element) nodeList.item(index);
			dealElement(ele,index);
		}
	}
	
	public void parseTag(Element element,String tagName) {
		NodeList nodeList=element.getElementsByTagName(tagName);
		for(int index=0;index<nodeList.getLength();index++) {
			Element ele = (Element) nodeList.item(index);
			dealElement(ele,index);
		}
	}	
}

我们可以将这个工具类压缩成一个jar文件,复制并且构建路径到需要用到的工程里,简化XML文档解析的操作过程,节约编码时间,将XML解析工具化。

下面给出一个测试代码:

package stu.crayue.about_xml.test;

import org.w3c.dom.Element;

import stu.crayue.about_xml.model.StudentInfo;
import stu.crayue.util.XMLParser;

/**
* @author Crayue
* @version 2019年11月10日 下午6:10:14
*/
public class Test {

	public static void main(String[] args) {
		new XMLParser() {
			
			@Override
			public void dealElement(Element element,int index) {
				StudentInfo stu = new StudentInfo();
				String id=element.getAttribute("id");
				stu.setId(id);
				String name = element.getAttribute("name");
				stu.setName(name);
				String sex = element.getAttribute("sex");
				stu.setSex(sex);
				String birthday = element.getAttribute("birtdhday");
				stu.setBirthday(birthday); 
				
				new XMLParser() {
					
					@Override
					public void dealElement(Element element,int index) {
						String hobbyString = element.getTextContent();
						stu.addHobby(hobbyString);
					}
				}.parseTag(element, "hobby");/获取element元素里面名为hobby的元素列表

				new XMLParser() {
					
					@Override
					public void dealElement(Element element,int index) {
						String introduce=element.getTextContent().trim();
						stu.setIntroduce(introduce);
					}
				}.parseTag(element, "introduce");/获取element元素里面名为introduce的元素列表
				System.out.println(stu); /输出students内容
			}
		}.parseTag(XMLParser.getDocument("/student.xml"), "student"); /获取document中的名为student的元素名列表
	}
}

输出结果截图:
在这里插入图片描述

package com.hexiang.utils; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.NodeList; /** * 本类是专门解析XML文件的,主要用于为系统读取自己的配置文件时提供最方便的解析操作 * @author HX * */ public class XmlManager { /** * 得到某节点下某个属性的值 * @param element 要获取属性的节点 * @param attributeName 要取值的属性名称 * @return 要获取的属性的值 * @author HX_2010-01-12 */ public static String getAttribute( Element element, String attributeName ) { return element.getAttribute( attributeName ); } /** * 获取指定节点下的文本 * @param element 要获取文本的节点 * @return 指定节点下的文本 * @author HX_2010-01-12 */ public static String getText( Element element ) { return element.getFirstChild().getNodeValue(); } /** * 解析某个xml文件,并在内存中创建DOM树 * @param xmlFile 要解析XML文件 * @return 解析某个配置文件后的Document * @throws Exception xml文件不存在 */ public static Document parse( String xmlFile ) throws Exception { // 绑定XML文件,建造DOM树 DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); DocumentBuilder db = dbf.newDocumentBuilder(); Document domTree = db.parse( xmlFile ); return domTree; } /** * 获得某节点下的某个子节点(指定子节点名称,和某个属性的值) * 即获取parentElement下名字叫childName,并且属性attributeName的值为attributeValue的子结点 * @param parentElement 要获取子节点的那个父节点 * @param childName 要获取的子节点名称 * @param attributeName 要指定的属性名称 * @param attributeValue 要指定的属性的值 * @return 符合条件的子节点 * @throws Exception 子结点不存在或有多个符合条件的子节点 * @author HX_2008-12-01 */ public static Element getChildElement( Element parentElement, String childName, String attributeName, String attributeValue ) throws Exception { NodeList list = parentElement.getElementsByTagName( childName ); int count = 0; Element curElement = null; for ( int i = 0 ; i < list.getLength() ; i ++ ) { Element child = ( Element )list.item( i ); String value = child.getAttribute( attributeName ); if ( true == value.equals( attributeValue ) ) { curElement =
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值