`
newspringwork
  • 浏览: 101661 次
  • 性别: Icon_minigender_1
  • 来自: 长沙
社区版块
存档分类
最新评论

Java解析XML

    博客分类:
  • XML
 
阅读更多

一、XML常见解析方式

常见解析XML的方法主要有DOM和SAX

1.DOM解析方式-基于文档树

DOM,即文档对象模型(Document Object Model),将XML文档解析成树状模型并将其放入内存来完成解析工作的,而后对文档的操作都是在这个树状模型上完成的。这个在内存中的文档树将是文档实际大小的几倍。

2.SAX解析方式-事件驱动

即XML简单应用程序接口-Simple API for XML,通读整个文档,根据文档内容产生事件,而把对这些事件的处理交由事件处理器处理。

3.DOM与SAX解析方式的对比

SAX DOM
顺序读入文档并产生相应事件,可以处理任何大小的XML文档 在内存中创建文档树,不适于处理大型XML文档。
只能对文档按顺序解析一遍,不支持对文档的随意访问。 可以随意访问文档树的任何部分,没有次数限制。
只能读取XML文档内容,而不能修改 可以随意修改文档树,从而修改XML文档。
开发上比较复杂,需要自己来实现事件处理器。 易于理解,易于开发。
对开发人员而言更灵活,可以用SAX创建自己的XML对象模型。 已经在DOM基础之上创建好了文档树。

 

二、Java中解析XML

Sun公司提供了 java API for XML Parsing(JAXP)接口来使用SAX和DOM,通过JAXP,我们可以使用任何与JAXP兼容的XML解析器。

1.基础类与待解析XML

<?xml version="1.0" encoding="UTF-8"?>
<MemInfo class="0501">
	<person no="1">
		<name>James</name>
		<age>32</age>
	</person>
	<person no="2">
		<name>Kim</name>
		<age>38</age>
	</person>
	<person no="3">
		<name>Joe</name>
		<age>24</age>
	</person>
</MemInfo>

 

public class ClassInfo {
	private String no;
	private List<Person> students;

	public String getNo() {
		return no;
	}

	public void setNo(String no) {
		this.no = no;
	}

	public List<Person> getStudents() {
		return students;
	}

	public void setStudents(List<Person> students) {
		this.students = students;
	}
}

 

public class Person {
	private String no;
	private String name;
	private byte age;

	public String getNo() {
		return no;
	}

	public void setNo(String no) {
		this.no = no;
	}

	public String getName() {
		return name;
	}

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

	public byte getAge() {
		return age;
	}

	public void setAge(byte age) {
		this.age = age;
	}
}

 2.SAX方式解析

import java.util.ArrayList;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

import com.alibaba.fastjson.JSONObject;

/**
 * SAX解析器
 */
public class MemInfoParser extends DefaultHandler {
	/**
	 * log4j日志
	 */
	protected static Logger log = LogManager.getLogger();

	private ClassInfo cls;
	private Person person;
	/**
	 * 
	 */
	private String preTag;

	/**
	 * 文档开始调用
	 */
	@Override
	public void startDocument() throws SAXException {
		cls = new ClassInfo();
		cls.setStudents(new ArrayList<>());
	}

	/**
	 * 文档结束调用
	 */
	@Override
	public void endDocument() throws SAXException {
		log.info("解析获得数据:" + JSONObject.toJSONString(cls));
	}

	/**
	 * 元素处理开始调用-多次
	 */
	@Override
	public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
		switch (qName) {
		case "MemInfo":
			cls.setNo(attributes.getValue("class"));
			break;
		case "person":
			person = new Person();
			person.setNo(attributes.getValue("no"));
			break;
		default:
			break;
		}
		preTag = qName;
	}

	/**
	 * 元素处理结束调用-多次
	 */
	@Override
	public void endElement(String uri, String localName, String qName) throws SAXException {
		switch (qName) {
		case "MemInfo":
			break;
		case "person":
			cls.getStudents().add(person);
			person = null;
			break;
		default:
			break;
		}
		preTag = null;
	}

	/**
	 * 处理TextNode文本节点调用-多次
	 */
	@Override
	public void characters(char[] ch, int start, int length) throws SAXException {
		//preTag为空,表示处理的是空白的文本节点,丢弃掉,PS:元素之间的空白部分SAX解析器会作为文本节点处理,如person、name节点间的空白
		if (preTag == null)
			return;
		// 文本内容
		String text = new String(ch, start, length);
		switch (preTag) {
		case "name":
			person.setName(text);
			break;
		case "age":
			person.setAge(Byte.parseByte(text));
			break;
		default:
			break;
		}
	}
}

 测试类:

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

import org.xml.sax.XMLReader;

public class SaxParserTest {
	public static void main(String[] args) throws Exception {
		String path = "/data/workspace/tec-demo/src/main/java/cn/tinyf/demo/xml/sax/MemInfo.xml";
		// 创建解析工厂
		SAXParserFactory factory = SAXParserFactory.newInstance();
		// 创建解析器
		SAXParser parser = factory.newSAXParser();
		// 得到读取器
		XMLReader reader = parser.getXMLReader();
		// 设置内容处理器
		MemInfoParser handler = new MemInfoParser();
		reader.setContentHandler(handler);
		// 读取xml文档
		reader.parse(path);
	}
}

 

3.DOM方式读写

 

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

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.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import com.alibaba.fastjson.JSONObject;

/**
 * XML解析-Dom实现
 */
public class MemInfoParser {

	public static void main(String[] args) {
		String path = "/data/workspace/tec-demo/src/main/java/cn/tinyf/demo/xml/MemInfo.xml";
		System.out.println(JSONObject.toJSONString(parser(path)));
	}

	public static ClassInfo parser(String docPath) {
		DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
		// 从 DocumentBuilderFactory获取 DocumentBuilder实例
		DocumentBuilder db;
		try {
			// 从 XML 文档获取 DOM 文档实例
			db = dbf.newDocumentBuilder();
			Document doc = db.parse(new File(docPath));
			/*
			 * 创建相关对象存储XML数据
			 */
			ClassInfo cls = new ClassInfo();
			List<Person> stuList = new ArrayList<>();
			cls.setStudents(stuList);
			// 获取文档节点中的班级信息
			cls.setNo(doc.getDocumentElement().getAttribute("class"));
			/*
			 * 获取所有学生节点,并遍历获取数据
			 */
			NodeList stuNodes = doc.getElementsByTagName("person");
			int len = stuNodes.getLength();
			for (int i = 0; i < len; i++) {
				Element stu = (Element) stuNodes.item(i);
				Node eltName = stu.getElementsByTagName("name").item(0);
				Node eltAge = stu.getElementsByTagName("age").item(0);
				Person person = new Person();
				person.setName(eltName.getFirstChild().getNodeValue());
				person.setNo(stu.getAttribute("no"));
				person.setAge(Byte.parseByte(eltAge.getFirstChild().getNodeValue()));
				stuList.add(person);
			}
			return cls;
		} catch (ParserConfigurationException e) {
			e.printStackTrace();
		} catch (SAXException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return null;
	}
}
/**
 * XML生成-dom方式
 */
public class MemInfoBuilder {
	/**
	 * log4j2日志
	 */
	protected static Logger log = LogManager.getLogger();

	public static void main(String[] args) {
		String xmlPath = "/data/workspace/tec-demo/src/main/java/cn/tinyf/demo/xml/dom/dom-data.xml";
		//
		DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
		// 从 DocumentBuilderFactory获取 DocumentBuilder实例
		DocumentBuilder db;
		try {
			// 从 XML 文档获取 DOM 文档实例
			db = dbf.newDocumentBuilder();
			Document doc = db.newDocument();
			/*
			 * 生成文档树
			 */
			// 根节点
			Element root = doc.createElement("MemInfo");
			// 设置根节点属性
			root.setAttribute("class", "0501");
			// 为根节点添加子节点数据
			root.appendChild(createStuElement(doc, "1", "James", 32));
			root.appendChild(createStuElement(doc, "2", "Kim", 38));
			root.appendChild(createStuElement(doc, "3", "Joe", 24));
			// 根节点添加到文档树
			doc.appendChild(root);
			/*
			 * 准备生成文件
			 */
			// 设置XML声明中standalone为yes,即没有dtd和schema作为该XML的说明文档,且不显示该属性
			doc.setXmlStandalone(true);
			// 创建TransformerFactory对象
			TransformerFactory tff = TransformerFactory.newInstance();
			// 创建Transformer对象
			Transformer tf = tff.newTransformer();
			//
			tf.setOutputProperty(OutputKeys.INDENT, "yes");
			// 输出到文件
			tf.transform(new DOMSource(doc), new StreamResult(new FileOutputStream(xmlPath)));
		} catch (ParserConfigurationException | FileNotFoundException | TransformerException e) {
			log.error(e);
		}
	}

	private static Element createStuElement(Document doc, String no, String name, int age) {
		Element stuElem = doc.createElement("person");
		stuElem.setAttribute("no", no);
		//创建姓名节点
		Element nameElem = doc.createElement("name");
		nameElem.appendChild(doc.createTextNode(name));
		//创建年龄节点
		Element ageElem = doc.createElement("age");
		ageElem.appendChild(doc.createTextNode(age + ""));
		//将姓名、年龄节点添加到学生节点中并返回
		stuElem.appendChild(nameElem);
		stuElem.appendChild(ageElem);
		return stuElem;
	}
}

 

三、其他解析器

1. JDOM

JDOM是一个开源项目,它基于树型结构,利用纯JAVA的技术对XML文档实现解析、生成、序列化以及多种操作。

Jdom可以和已有的XML技术如Simple API for XML (SAX)和 Document Object Model (DOM)相互协作。

实例>>

 

2.dom4j

dom4j是一个开源的Java的XML API,是jdom的升级品,用来读写XML文件的。dom4j是一个十分优秀的JavaXML API,具有性能优异、功能强大和极其易使用的特点,它的性能超过sun公司官方的dom技术。

分享到:
评论

相关推荐

    JAVA 解析XML生成XML文档实例

    JAVA 解析XML和生成XML文档源码。比较全 1.DOM生成和解析XML文档 2.SAX生成和解析XML文档 3.DOM4J生成和解析XML文档 4.JDOM生成和解析XML

    java解析xml字符串

    ### Java解析XML字符串 在给定的代码示例中,我们看到了如何使用JDOM库来解析一个XML字符串,并对其进行操作。下面我们将详细解析这个过程: 1. **初始化XML源**:首先,将XML字符串转化为`StringReader`对象,这...

    java解析XML文件

    Java解析XML文件是Java开发中常见的一项任务,XML(eXtensible Markup Language)作为一种结构化数据存储格式,被广泛用于数据交换、配置文件和Web服务等场景。本篇文章将详细探讨Java如何利用DOM4J库来解析XML文件...

    使用java解析XML文件,解析完之后将解析结果导入mysql数据库中

    本教程将介绍如何使用Java解析XML文件,并将解析结果导入MySQL数据库。 首先,我们需要引入处理XML的Java库——JAXB(Java Architecture for XML Binding)和DOM(Document Object Model)API。JAXB用于对象与XML...

    JAVA解析XML

    ### JAVA解析XML知识点详解 #### 一、XML与JAVA的关系 **XML (eXtensible Markup Language)** 是一种用于标记电子文件使其具有结构性的标记语言。由于其平台无关性、语言无关性和系统的无关性,XML成为了数据交换...

    详 解Java解析XML

    以下是一个简单的DOM解析XML的例子: ```java import javax.xml.parsers.*; import org.w3c.dom.*; import java.io.*; public class DOMExample { public static void main(String[] args) { try { ...

    JAVA 解析xml

    JAVA 解析xml多种方法 JAVA 解析xml多种方法 JAVA 解析xml多种方法 JAVA 解析xml多种方法 JAVA 解析xml多种方法 JAVA 解析xml多种方法 JAVA 解析xml多种方法

    java 解析xml 多级

    Java作为一种广泛使用的后端编程语言,提供了多种方式来解析XML文档,使得处理多级嵌套的数据变得可能。本文将详细讲解如何在Java中解析XML,特别是针对多级结构的情况。 首先,Java提供了两种主要的API来处理XML:...

    java解析XML的四种方式

    ### Java解析XML的四种方式详解 #### 一、DOM(Document Object Model) DOM是一种平台和语言中立的接口,它将XML文档表示为一个树结构,使得程序可以创建、读取、更新或删除树中的元素。DOM实现了W3C的标准,能够...

    java解析xml并导入数据库(dom4j).doc

    Java 解析 XML 并导入数据库(DOM4J) Java 解析 XML 并导入数据库是指使用 Java 语言将 XML 文件解析并将其内容导入到数据库中。下面是使用 DOM4J 库来实现此功能的相关知识点: 一、XML 文件解析 XML...

    java解析xml的四种经典方法

    Java解析XML的四种经典方法是XML处理中常用的技术,它们分别是DOM、SAX、StAX和JDOM。每种方法都有其独特的特性和适用场景,下面将详细介绍这四种方法。 1. DOM(Document Object Model)解析: DOM是W3C制定的一种...

    Java 解析xml 存入mongodb 返回org.json json包

    本篇将详细介绍如何使用Java解析XML,将数据存入MongoDB,并返回org.json JSON包。 首先,解析XML通常有两种主要方法:DOM(Document Object Model)和SAX(Simple API for XML)。DOM一次性加载整个XML文档到内存...

    java解析xml——dom

    ### Java解析XML——DOM详解 #### 一、DOM解析概念 **Document Object Model (DOM)**是一种平台和语言中立的接口,它允许程序和脚本动态地访问和更新文档的内容、结构和样式。DOM最初是为HTML设计的,但后来也被...

    java解析XML的4种经典方法

    Java解析XML的四种经典方法主要涵盖DOM、SAX、StAX和JDOM这四种方式,每种方法都有其独特的优势和适用场景。 1)DOM(JAXP Crimson 解析器) DOM(Document Object Model)是W3C推荐的一种XML解析标准,它将XML...

    详解Java解析XML的四种方法

    本文将深入探讨Java解析XML的四种主要方法。 1. DOM(Document Object Model)解析: DOM解析器将整个XML文档加载到内存中,创建一个树形结构,允许开发者通过节点遍历和操作XML。例如,Java的`javax.xml.parsers....

    java 解析XML性能对比分析Demo

    本文将深入探讨几种不同的XML解析方法,并通过实际的“Java解析XML性能对比分析Demo”来展示它们的性能差异。我们将讨论DOM、SAX、JDOM、DOM4J和JAXB这五种解析器,以及它们各自的特点和适用场景。 1. DOM(文档...

    Java解析XML工具类--(java源码)

    * 本类是专门解析XML文件的,主要用于为系统读取自己的配置文件时提供最方便的解析操作 * @author HX * */ public class XmlManager { /** * 得到某节点下某个属性的值 * @param element 要获取属性的...

    java解析xml的4种方法和json格式

    本篇文章将详细介绍Java解析XML的四种方法以及JSON格式的相关知识。 一、DOM解析 DOM(Document Object Model)是W3C推荐的一种解析XML的标准方法,它将整个XML文档加载到内存中,形成一个树形结构,便于遍历和操作...

    java解析xml生成json对象

    在Java编程环境中,XML(可...总的来说,Java解析XML生成JSON对象的能力使得数据在不同平台和应用间无缝交换成为可能。通过学习和使用这样的工具类,开发者可以更高效地处理XML数据,并将其集成到基于JSON的系统中。

    java解析xml动态生成树形菜单结构

    总结起来,实现“java解析xml动态生成树形菜单结构”的项目,需要掌握以下核心知识点: 1. Java的DOM解析XML,构建树形数据结构。 2. 设计和实现无限层级的树形菜单数据模型。 3. 使用`JSTree`库在前端渲染树形菜单...

Global site tag (gtag.js) - Google Analytics