xml解析

XML(可扩展标记语言)

Extensive Markup Language

概述:
xml:即可扩展标记语言,xml是互联网数据传输的重要工具,它可以跨越互联网任何的平台,不受编程语言和操作系统的限制,可以说它是一个拥有互联网最高级别通行证的数据携带者。xml是当前处理结构化文档信息中相当给力的技术,xml有助于在服务器之间穿梭结构化数据,这使得开发人员更加得心应手的控制数据的存储和传输。
xml用于标记电子文件使其具有结构性的标记语言,可以用来标记数据、定义数据类型,是一种允许用户对自己的标记语言进行定义的源语言。Xml是标准通用标记语言(SGML)的子集,非常适合Web传输。XML提供统一的方法来描述和交换独立于应用程序或供应商的结构化数据。

通过数据两端通过统一的格式进行数据的存储与传输,并提供通用的读取方式

xml的特点及作用:
特点:
xml与操作系统、编程语言的开发平台都无关;
实现不同系统之间的数据交互。
作用:
配置应用程序和网站;
数据交互;
Ajax基石。
在配置文件里边所有的配置文件都是以XMl的格式来编写的。

语法:

标题行: <?xml version="1.0" encoding="UTF-8"?>
其余书写方式类似于html双标签形式书写,但与html固定标签不同的是,xml中标签为自定义,也就是说可以自定义名字标签

由两部分组成 标题行与主体(注意:主体中以双标签形式进行数据的标志,根标签只能有一个,标签名自定义但通常以保存数据的类名进行定义)

<!-- 注释 -->
<!-- 标题行:用于提示读取者当前文档的类别 以及编码字符集 -->
<?xml version="1.0" encoding="UTF-8"?>
 
 <!-- 内容:使用指定格式进行数据的存储 -->
 <!-- 在一个根标签下进行包裹书写数据 (注意层级关系) -->
 
 <!-- 例如:存储Student集合  -->
 <!-- 标签成对出现 -->
 <students>
	<student>
		<name>张三</name>
		<sex></sex>
		<age>18</age>
	</student>
	<student>
		<name>李四</name>
		<sex></sex>
		<age>28</age>
	</student>
 </students>
import java.io.Serializable;

public class Student implements Serializable {
	private static final long serialVersionUID = -1105845831799085846L;
	private String name;
	private String sex;
	private String age;

	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 getAge() {
		return age;
	}

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

	public Student(String name, String sex, String age) {
		super();
		this.name = name;
		this.sex = sex;
		this.age = age;
	}

	public Student() {
		super();
	}

	@Override
	public String toString() {
		return "Student [name=" + name + ", sex=" + sex + ", age=" + age + "]";
	}

}

xml解析

①SAX解析

sax解析是xml文档最开始提供的解析方式。

SAX(Simple API for XML)解析器采用了基于事件的模型,它在解析XML文档的时候可以触发一系列的事件,当发现给定的tag的时候,它可以激活一个回调方法,告诉该方法指定的标签已经找到。SAX对内存的要求通常会比较低,因为它让开发人员自己来决定所要处理的tag.特别是当开发人员只需要处理文档中所包含的部分数据时,SAX这种扩展能力得到了更好的体现。但用SAX解析器的时候编码工作会比较困难,而且很难同时访问同一个文档中的多处不同数据。

使用流读取,采用方法回调进行xml文件的读取,在进读取时如果发现相应的回调方法则执行

【优点】

​ ①不需要等待所有数据都被处理,分析就能立即开始。
​ ②只在读取数据时检查数据,不需要保存在内存中。
​ ③可以在某个条件得到满足时停止解析,不必解析整个文档。
​ ④效率和性能较高,能解析大于系统内存的文档。

【缺点】

​ ①需要应用程序自己负责处理逻辑(例如维护父/子关系等),文档越复杂程序就越复杂。
​ ②单向导航,无法定位文档层次,很难同时访问同一文档的不同部分数据,不支持XPath。

import java.util.ArrayList;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

//自定义sax解析器
//1自定义sax解析器继承默认解析器重写解析方法
public class SaxParseHandler extends DefaultHandler {
	String str = "";
	Student student = null;
	ArrayList<Student> students = new ArrayList<>();

	// 当解析起始标签时执行方法
	@Override
	public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
		if (qName.equals("student")) {
			student = new Student();
		}
	}

	// 当解析到结束标签时执行的回调方法
	@Override
	public void endElement(String uri, String localName, String qName) throws SAXException {
		if (qName.equals("name")) {
			student.setName(str);
		} else if (qName.equals("sex")) {
			student.setSex(str);
		} else if (qName.equals("age")) {
			student.setAge(str);
		} else if (qName.equals("student")) {
			students.add(student);
		}

	}

	// 当解析文本时执行的回调方法
	@Override
	public void characters(char[] ch, int start, int length) throws SAXException {
		// ch存储的是所有字节数据
		// start当前文本起始位置
		// length当前文本长度
		str = new String(ch, start, length);
	}

	public static void main(String[] args) throws Exception {
		// sax解析xml文件书写步骤
		// 1自定义sax解析器继承默认解析器重写解析方法
		// 2创建sax解析工厂对象
		SAXParserFactory saxf = SAXParserFactory.newInstance();
		// 3创建sax解析对象
		SAXParser saxp = saxf.newSAXParser();
		// 4创建自定义解析器
		SaxParseHandler sph = new SaxParseHandler();
		// 5使用解析对象执行相应解析器解析xml
		saxp.parse("F://test/students.xml", sph);
		System.out.println(sph.students);
	}
}

②DOM解析

​ DOM(Document Object Model)是用与平台和语言无关的方式表示XML文档的官方W3C标准。DOM是以层次结构组织的节点或信息片断的集合。这个层次结构允许开发人员在树中寻找特定信息。分析该结构通常需要加载整个文档和构造层次结构,然后才能做任何工作。由于它是基于信息层次的,因而DOM被认为是基于树或基于对象的。

DOM解析是将数据先全部加载下来,之后进行解析可以解析文档任意位置数据

【优点】

​ ①允许应用程序对数据和结构做出更改。
​ ②访问是双向的,可以在任何时候在树中上下导航,获取和操作任意部分的数据。

【缺点】

​ ①通常需要加载整个XML文档来构造层次结构,消耗资源大。

注意:在使用dom解析是换行文本都会当做节点标签

import java.io.IOException;
import java.util.ArrayList;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
public class DomTest {
	public static void main(String[] args) throws Exception {
		ArrayList<Student> list = new ArrayList<>();
		// 1.创建dom解析器工厂对象
		DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
		// 2.使用dom解析器工厂对象创建dom解析器对象
		DocumentBuilder db = dbf.newDocumentBuilder();
		// 3使用dom解析器对象解析指定xml将解析数据存储在dom对象中
		Document dom = db.parse("F://test/students.xml");
		// 4使用dom对象中的方法获取数据
		// 获取dom中所有指定标签对象
		// NodeList nameList = dom.getElementsByTagName("name");
		// 获取指定标签集合长度
		// System.out.println(nameList.getLength());
		// 获取集合中指定标签
		// nameList.item(0);//获取第一个
		// nameList.item(0).getFirstChild();//获取第一个子标签
		// nameList.item(0).getFirstChild().getTextContent();//获取文本标签数据

		// (1)获取标签对象
		NodeList studentNodeList = dom.getElementsByTagName("student");// 获取所有student标签对象集合
		// (2)遍历标签
		for (int i = 0; i < studentNodeList.getLength(); i++) {
			Student s = new Student();
			// 获取标签子节点标签
			Node node = studentNodeList.item(i);// 获取指定索引节点标签
			// 继续获取子节点标签
			NodeList childNodes = node.getChildNodes();
			// 遍历属性标签
			for (int j = 0; j < childNodes.getLength(); j++) {
				// 获取指定索引节点标签
				Node item = childNodes.item(j);
				// 判断是否是文本节点 不是文本节点则继续获取子节点标签
				if (!item.getNodeName().equals("#text")) {
					// 获取节点标签数据
					// System.out.println(item.getTextContent());
					if (item.getNodeName().equals("name")) {
						s.setName(item.getTextContent());
					} else if (item.getNodeName().equals("sex")) {
						s.setSex(item.getTextContent());
					} else if (item.getNodeName().equals("age")) {
						s.setAge(item.getTextContent());
					}
				}
			}
			list.add(s);
		}
		System.out.println(list);
	}
}

③JDOM解析

​ JDOM(Java-based Document Object Model)的目的是成为Java特定文档模型,它简化与XML的交互并且比使用DOM实现更快。由于是第一个Java特定模型,JDOM一直得到大力推广和促进。正在考虑通过“Java规范请求JSR-102”将它最终用作“Java标准扩展”。从2000年初就已经开始了JDOM开发。
​ JDOM与DOM主要有两方面不同。首先,JDOM使用具体类而不使用接口。这在某些方面简化了API,但是也限制了灵活性。第二,API大量使用了Collections类,简化了那些已经熟悉这些类的Java开发者的使用。
​ JDOM文档声明其目的是“使用20%(或更少)的精力解决80%(或更多)Java/XML问题”(根据学习曲线假定为20%)。JDOM对于大多数Java/XML应用程序来说当然是有用的,并且大多数开发者发现API比DOM容易理解得

多。JDOM还包括对程序行为的相当广泛检查以防止用户做任何在XML中无意义的事。然而,它仍需要您充分理解XML以便做一些超出基本的工作(或者甚至理解某些情况下的错误)。这也许是比学习DOM或JDOM接口都更有意义的工作。

​ JDOM自身不包含解析器。它通常使用SAX2解析器来解析和验证输入XML文档(尽管它还可以将以前构造的DOM表示作为输入)。它包含一些转换器以将JDOM表示输出成SAX2事件流、DOM模型或XML文本文档。JDOM是在Apache许可证变体下发布的开放源码。

【优点】

​ ①使用具体类而不是接口,简化了DOM的API。
​ ②大量使用了Java集合类,方便了Java开发人员。

【缺点】

​ ①没有较好的灵活性。
​ ②性能较差。

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

import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.JDOMException;
import org.jdom2.input.SAXBuilder;

public class JDomTest {
	public static void main(String[] args) throws JDOMException, IOException {
		ArrayList<Student> list = new ArrayList<>();
		// 使用jdom解析xml文件
		// 1导入jdom相应jar包
		// 2创建sax解析器(dom一直使用的sax的解析器加载文件)
		SAXBuilder sb = new SAXBuilder();
		// 3使用sax解析器加载指定xml文件 返回存储所有数据的dom对象
		Document dom = sb.build(new File("F://test/students.xml"));
		// 获取根元素对象
		Element rootElement = dom.getRootElement();
		// 获取指定元素对象所有子元素
		List<Element> studentList = rootElement.getChildren();
		// 遍历元素集合
		for (Element student : studentList) {
			Student s = new Student();
           // Student s = new Student(student.getChildText("name"), student.getChildText("sex"), student.getChildText("age"));
			// 获取每个student元素的子元素(属性集合)
			List<Element> filedList = student.getChildren();
			// 继续遍历属性集合
			for (Element filed : filedList) {
				if (filed.getName().equals("name")) {
					s.setName(filed.getValue());
				} else if (filed.getName().equals("age")) {
					s.setAge(filed.getValue());
				} else if (filed.getName().equals("sex")) {
					s.setSex(filed.getValue());
					 
				}
			}
			list.add(s);
		}
		System.out.println(list);
	}
}

④DOM4J解析

​ DOM4J(Document Object Model for Java)是JDOM的一种智能分支。它合并了许多超出基本XML文档表示的功能,为支持所有这些功能,DOM4J使用接口和抽象基本类方法。DOM4J大量使用了API中的Collections类,但是在许多情况下,它还提供一些替代方法以允许更好的性能或更直接的编码方法。直接好处是,虽然DOM4J付出了更复杂的API的代价,但是它提供了比JDOM大得多的灵活性。

​ DOM4J是一个非常非常优秀的Java XML API,具有性能优异、功能强大和极端易用使用的特点,同时它也是一个开放源代码的软件。如今你可以看到越来越多的Java软件都在使用DOM4J来读写XML,特别值得一提的是连Sun的JAXM也在用DOM4J.

【优点】

​ ①大量使用了Java集合类,方便Java开发人员,同时提供一些提高性能的替代方法。
​ ②有很好的性能。

【缺点】

​ ①大量使用了接口,API较为复杂。

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

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

public class DOM4JTest {
	public static void main(String[] args) throws Exception {
		// 1导入dom4j相应jar包
		// 2创建sax解析器对象(dom4j本身没有解析器,使用sax解析器读取xml文件)
		SAXReader saxReader = new SAXReader();
		// 3使用sax解析器读取指定xml文件返回dom对象
		Document dom = saxReader.read(new File("F://test/students.xml"));
		// 4获取根元素对象
		Element rootElement = dom.getRootElement();
		// 5获取根元素迭代器(迭代所有子元素)
		Iterator iterator = rootElement.elementIterator();
		while (iterator.hasNext()) {// 是否存在下一个元素
			// 如果存在则获取强转为元素对象
			Element e = (Element) iterator.next();
			// 继续遍历
			// Iterator elementIterator = e.elementIterator();
			// while (elementIterator.hasNext()) {
			// Element e2 = (Element) elementIterator.next();
			// System.out.println(e2.getName()+"=>"+e2.getText());
			// }
			// 获取指定元素子元素中指定元素对象
			Student s = new Student(e.elementText("name"), e.elementText("sex"), e.elementText("age"));
			System.out.println(s);
		}
	}
}
已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 数字20 设计师:CSDN官方博客 返回首页