欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

XML解析

程序员文章站 2022-04-30 10:00:11
...

XML文件解析

首先我以“学生信息”举例,给一个xml文件的代码:
student.tag.xml

<?xml version="1.0" encoding="UTF-8"?>
<students>
	<student>
		<id>00001</id>
		<name>小张</name>
		<sex></sex>
		<birtdhday>2000-10-3</birtdhday>
		<hobbies>
			<hobby>游泳</hobby>
			<hobby>装逼</hobby>
			<hobby>睡觉</hobby>
		</hobbies>
		<introduce>
			无所事事的小混混;
		</introduce>
	</student>
	<student>
		<id>00002</id>
		<name>晓珊</name>
		<sex></sex>
		<birtdhday>2001-1-21</birtdhday>
		<hobbies>
			<hobby>游泳</hobby>
			<hobby>画画</hobby>
			<hobby>学习</hobby>
		</hobbies>
		<introduce>
			琴棋书画样样精通;
		</introduce>
	</student>
</students>

再给另一个xml文件:
student.att.xml

<?xml version="1.0" encoding="UTF-8"?>
<students>
	<student id="00001" name="小张" sex="男" birtdhday="2000-10-3">
		<hobby>游泳</hobby>
		<hobby>装逼</hobby>
		<hobby>睡觉</hobby>
		<introduce>
			无所事事的小混混;
		</introduce>
	</student>
	<student id="00002" name="晓珊" sex="女" birtdhday="2001-1-21">
		<hobbies>
			<hobby>游泳</hobby>
			<hobby>画画</hobby>
			<hobby>学习</hobby>
		</hobbies>
		<introduce>
			琴棋书画样样精通;
		</introduce>
	</student>
</students>

前一种着重使用标签,第二种方式综合属性和标签。这两种都可以表达学生信息,没有哪种是标准方式。

分别给出两个xml文件的解析类:
TestParseTag.java

package com.mec.about_xml.test;

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 class TestParseTag {

	public static void main(String[] args) {
		try {
			InputStream is = TestParseTag.class.getResourceAsStream("/student.tag.xml");
			DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
			DocumentBuilder db = dbf.newDocumentBuilder();
			Document document = db.parse(is);
			
			NodeList studentList =  document.getElementsByTagName("student");
			for (int index = 0; index < studentList.getLength(); index++) {
				Element student = (Element) studentList.item(index);
				Element idElement = (Element) student.getElementsByTagName("id").item(0);
				String id = idElement.getTextContent();
				
				Element nameElement = (Element) student.getElementsByTagName("name").item(0);
				String name = nameElement.getTextContent();
				
				Element introduceElement = (Element) student.getElementsByTagName("introduce").item(0);
				String introduce = introduceElement.getTextContent();
				
				System.out.println(id + ", " + name);
				System.out.println("[" + introduce.trim() + "]");
			}
		} catch (ParserConfigurationException e) {
			e.printStackTrace();
		} catch (SAXException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

}

TestParseAttribute.java

package com.mec.about_xml.test;

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;

import com.mec.about_xml.model.StudentInfo;

public class TestParseAttribute {

	public static void main(String[] args) {
		try {
			InputStream is = TestParseAttribute.class.getResourceAsStream("/student.att.xml");
			DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
			DocumentBuilder db = dbf.newDocumentBuilder();
			Document document = db.parse(is);
			
			NodeList studentList = document.getElementsByTagName("student");
			for (int i = 0; i < studentList.getLength(); i++) {
				StudentInfo stu = new StudentInfo();
				
				Element student = (Element) studentList.item(i);
				String id = student.getAttribute("id");
				String name = student.getAttribute("name");
				String sex = student.getAttribute("sex");
				String birthday = student.getAttribute("birtdhday");
				
				NodeList hobbyList = student.getElementsByTagName("hobby");
				for (int j = 0; j < hobbyList.getLength(); j++) {
					Element hobby = (Element) hobbyList.item(0);
					String hobbyString = hobby.getTextContent();
					stu.addHobby(hobbyString);
				}
				
				stu.setId(id);
				stu.setName(name);
				stu.setSex(sex);
				stu.setBirthday(birthday);
				
				String introduce = student.getElementsByTagName("introduce")
						.item(0).getTextContent().trim();
				stu.setIntroduce(introduce);
				
				System.out.println(stu);
			}
		} catch (ParserConfigurationException e) {
			e.printStackTrace();
		} catch (SAXException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

}

观察上面的两个解析类:TestParseTag类和TestParseAttribute类;我们发现这两个解析类有很多的相似之处。
例如:

			DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
			DocumentBuilder db = dbf.newDocumentBuilder();
			InputStream is = TestParseAttribute.class.getResourceAsStream("/student.att.xml");
			Document document = db.parse(is);

这四行代码可以认为是一个固定套路。而且从最后一行可以看出前两行代码就是要得到一个DocumentBuilder类的对象,而且,对于不同的XML文件解析,这个对象只需要一个就够了!
我们就可以将XML解析过程“工具化”。

XML文件解析过程的工具化

这里先引入一个概念——静态块;
静态块的特点是在类加载的时候就执行,且只执行一次,以后不再执行。

下面我给出XMLParse.java

package com.mec.util;

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) {
			System.out.println("xmlPath[" + xmlPath + "]不存在!");
			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);
		}
	}
	
}

编写调用XMLParse.java的类Test:
首先,先建立辅助我们解析XML文件的类:StudentInfo.java

package com.mec.about_xml.model;

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

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) {
		if (hobbies.contains(hobby)) {
			return;
		}
		hobbies.add(hobby);
	}

	@Override
	public String toString() {
		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();
	}
	
}

Test.java

package com.mec.about_xml.test;

import org.w3c.dom.Element;

import com.mec.about_xml.model.StudentInfo;
import com.mec.util.XMLParser;

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");
				
				new XMLParser() {
					@Override
					public void dealElement(Element element, int index) {
						String introduce = element.getTextContent().trim();
						stu.setIntroduce(introduce);
					}
				}.parseTag(element, "introduce");
				
				System.out.println(stu);
			}
		}.parseTag(XMLParser.getDocument("/student.att.xml"), "student");
	}

}

结果显示:
XML解析
我们可以把我们的工具类打成jar包,方便以后我们的调用。