XML 指可扩展标记语言(EXtensible Markup Language), 是一种很像HTML的标记语言,但是XML用于传输和存储数据的.
XML的解析方式分有:(1)DOM解析;(2)SAX解析;(3)STAX解析;(4)JDOM解析;(5)DOM4J解析。其中前两种属于基础方法,是官方提供的平台无关的解析方式;后两种属于扩展方法,它们是在基础的方法上扩展出来的,只适用于java平台。
针对以下的XML 文件,分别采用以上提到的五种方式进行解析:
grndpa
75
Writing brush
grndma
70
Read book
father
48
Play golf
mom
45
Grow flowers
son
20
Play basketball
DOM模式解析XML,是把整个XML文档当成一个对象来处理,会先把整个文档读入到内存里。是基于树的结构,通常需要加载整文档和构造DOM树,然后才能开始工作。
@Test
public void domTest() throws ParserConfigurationException, IOException, SAXException {
//创建待解析的XML文件,并指定目标
File file=new File("src/main/resources/xmlanalysisTest.xml");
//1.创建DocumentBuilderFactory
DocumentBuilderFactory documentBuilderFactory= DocumentBuilderFactory.newInstance();
// 2.用工厂对象创建DocumentBuilder对象
DocumentBuilder documentBuilder=documentBuilderFactory.newDocumentBuilder();
// 3.用DocumentBuilder对象将xml文件加载进内存,用Document对象接收
Document document= documentBuilder.parse(file);
// 4.获取到所有family节点,返回NodeList
NodeList memberList= document.getElementsByTagName("memeber");
// 5.循环遍历NodeList里的family节点
/* for (int i=0; i
优点:
缺点:
使用场合:文档较小,且需要修改文档内容
SAX的全称是Simple APIs for XML,也即XML简单应用程序接口。SAX处理的特点是基于事件流的。分析能够立即开始,而不是等待所有的数据被处理。而且,由于应用程序只是在读取数据时检查数据,因此不需要将数据存储在内存中。这对于大型文档来说是个巨大的优点。事实上,应用程序甚至不必解析整个文档;它可以在某个条件得到满足时停止解析。sax分析器在对xml文档进行分析时,触发一系列的事件,应用程序通过事件处理函数实现对xml文档的访问,因为事件触发是有时序性的,所以sax分析器提供的是一种对xml文档的顺序访问机制,对于已经分析过的部分,不能再重新倒回去处理。
SAX解析方式:逐行扫描文档,一边扫描一边解析。相比于DOM,SAX可以在解析文档的任意时刻停止解析解析,是一种速度更快,更高效的方法。
SAX 是推模式的,所有的操作在解析器自动控制下进行,所有事件都会处理,不管需不需要解析整个文档,解析器都会自动启动解析任务,然后按顺序向下解析,直到解析完成才终止。 简单说来,推模式,就是你把如何操作通通告诉解析器,之后,解析器自动去完成所有解析任务,你不能做任何干涉了。
public class FamilyHandler extends DefaultHandler {
@Override
public void startDocument() throws SAXException {
super.startDocument();
System.out.println("解析XML 文件开始");
}
@Override
public void endDocument() throws SAXException {
super.endDocument();
System.out.println("解析XML 文件结束");
}
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
super.startElement(uri, localName, qName, attributes);
if("member".equals(qName)){
int length = attributes.getLength();
//遍历属性
for (int i=0;i
优点:
缺点:
适用于:文档较大,只需要读取文档数据。
Java 6.0对XML支持的新特性有许多方面。比如StAX、针对XML-Web服务的Java架构(JAX-WS)2.0、针对XML绑定的API(JAXB)2.0、XML数字签名API,甚至还支持SQL:2003 'XML’数据类型。
StAX是Streaming API for XML的缩写,是一种针对XML的流式拉分析API。StAX是一个基于JAVA API用于解析XML文档,类似SAX解析器的方式
StAX 是拉模式的,可以由用户根据需要控制需要处理事件类型及何时终止解析任务,用户调用一次next(),解析器就进行一次向下解析,完全在用户的控制下进行解析操作,在需要的解析工作已经完成时,可以随时终止解析。简单来说,拉模式就像抽纸,随用随拉,需要时就拉一下,不需要时,它不会自动推出来。你可以一直拉把一盒抽纸拉完,也可以按自己需要只拉几张。
StAX的API可以读取和写入XML文档。
@Test
public void StaxTest() throws FileNotFoundException, XMLStreamException {
//创建XML流工程
XMLInputFactory factory = XMLInputFactory.newInstance();
InputStream resourceAsStream = new FileInputStream("src/main/resources/xmlanalysisTest.xml");
//创建XML事件读取流
XMLEventReader reader = factory.createXMLEventReader(resourceAsStream);
while (reader.hasNext()){
XMLEvent event = reader.nextEvent();
//如果是开始元素
if (event.isStartElement()){
//读取开始元素
StartElement startElement = event.asStartElement();
String name= startElement.getName().toString();
// 获取属性
Iterator iterator = startElement.getAttributes();
while (iterator.hasNext()){
Attribute obj= (Attribute) iterator.next();
System.out.println(obj.getName() +":" +obj.getValue());
}
System.out.println("<" + name +">");
}
//如果是文本
if (event.isCharacters()){
//获取文本值
String str= event.asCharacters().getData();
if(!"".equals(str.trim())){
System.out.println(str);
}
}
}
}
应该使用的StAX解析器的时候:
SAX的缺点
因为它是在一个处理的方式,而不是随机访问XML文档。
如果需要跟踪的数据分析器已经看到或更改项目的顺序,必须编写代码和数据存储以自己方式处理。
JDOM是处理xml的纯java api.使用具体类而不是接口.JDOM具有树的遍历,又有SAX的java规则.JDOM与DOM主要有两方面不同。
首先,JDOM仅使用具体类而不使用接口。这在某些方面简化了API,但是也限制了灵活性。
第二,API大量使用了Collections类,简化了那些已经熟悉这些类的Java开发者的使用。
JDOM自身不包含解析器。它通常使用SAX2解析器来解析和验证输入XML文档(尽管它还可以将以前构造的DOM表示作为输入)。它包含一些转换器以将JDOM表示输出成SAX2事件流、DOM模型或XML文本文档。
@Test
public void jbomTest() throws IOException, JDOMException {
//(1)创建SAXBuilder对象
SAXBuilder saxBuilder = new SAXBuilder();
//(2)调用build方法获得Document对象
Document document = saxBuilder.build(new FileInputStream("src/main/resources/xmlanalysisTest.xml"));
//(3)获取根节点
Element books = document.getRootElement();
//(4)获取根节点的直接子节点集合
List booksChildren = books.getChildren();
//(5)遍历
for(int i = 0; i < booksChildren.size(); i++){
//获取book节点
Element member = booksChildren.get(i);
//获取属性的集合
List attributes = member.getAttributes();
//遍历属性
for(Attribute attr : attributes){
System.out.println("属性名:"+attr.getName()+"\t属性值:"+attr.getValue());
}
}
System.out.println("--------------------------------------------");
for(int i = 0; i < booksChildren.size(); i++){
//获取book节点
Element member = booksChildren.get(i);
//获取book的子节点
List children = member.getChildren();
//遍历节点
for(Element ele : children){
System.out.println("节点名:"+ele.getName()+"\t节点值:"+ele.getValue());
}
}
}
优点:
1、是基于树的处理xml的java api,把树加载到内存中.
2、没有向下兼容的限制,所以比DOM简单.
3、速度快.
4、具有SAX的java 规则.
缺点:
1、不能处理大于内存的文档.
2、JDOM表示XML文档逻辑模型,不能保证每个字节真正变换.
3、 针对实例文档不提供DTD与模式的任何实际模型.
4、 不支持于DOM中相应遍历包.
DOM4J有更复杂的api,所以dom4j比jdom有更大的灵活性.DOM4J性能最好,连Sun的JAXM也在用DOM4J.目前许多开源项目中大量采用DOM4J,例如大名鼎鼎的Hibernate也用DOM4J来读取XML配置文件。如果不考虑可移植性,那就采用DOM4J.
先在maven中引入jar包:
dom4j
dom4j
1.6.1
创建实体类
public class Family {
private String id;
private String Seniority;
private String age;
private String hobby;
public String getId() {
return id;
}
public Family(String id, String seniority, String age, String hobby) {
this.id = id;
Seniority = seniority;
this.age = age;
this.hobby = hobby;
}
@Override
public String toString() {
return "Family{" +
"id='" + id + ''' +
", Seniority='" + Seniority + ''' +
", age='" + age + ''' +
", hobby='" + hobby + ''' +
'}';
}
public void setId(String id) {
this.id = id;
}
public String getSeniority() {
return Seniority;
}
public void setSeniority(String seniority) {
Seniority = seniority;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
public String getHobby() {
return hobby;
}
public void setHobby(String hobby) {
this.hobby = hobby;
}
}
dom4j解析xml:
@Test
public void dom4jTest() throws DocumentException {
// 1.创建SAXReader对象,
SAXReader saxReader = new SAXReader();
//2.读取XML文件
Document read = saxReader.read("src/main/resources/xmlanalysisTest.xml");
//3.通过Document 对象获取根元素
Element rootElement = read.getRootElement();
//4. 通过根元素获取book
//element() 和elements()都可以获取标签签名查找子元素
List family = rootElement.elements("memeber") ;
//5.遍历,每一个book标签转换为family类
for(Element memeber: family){
String Seniority=memeber.elementText("Seniority");
String age = memeber.elementText("age");
String hobby= memeber.elementText("hobby");
String id = memeber.attributeValue("id");
System.out.println(new Family(id,Seniority,age,hobby));
System.out.println("=================================");
}
}
优点:
缺点:
DOM4J性能最好,连Sun的JAXM也在用DOM4J。目前许多开源项目中大量采用DOM4J,例如大名鼎鼎的Hibernate也用DOM4J来读取XML配置文件。如果不考虑可移植性,那就采用DOM4J。
JDOM和DOM在性能测试时表现不佳,在测试10M文档时内存溢出,但可移植。在小文档情况下还值得考虑使用DOM和JDOM.虽然JDOM的开发者已经说明他们期望在正式发行版前专注性能问题,但是从性能观点来看,它确实没有值得推荐之处。另外,DOM仍是一个非常好的选择。DOM实现广泛应用于多种编程语言。它还是许多其它与XML相关的标准的基础,因为它正式获得W3C推荐(与基于非标准的Java模型相对),所以在某些类型的项目中可能也需要它(如在JavaScript中使用DOM)。
SAX表现较好,这要依赖于它特定的解析方式-事件驱动。一个SAX检测即将到来的XML流,但并没有载入到内存(当然当XML流被读入时,会有部分文档暂时隐藏在内存中)。
总结:如果XML文档较大且不考虑移植性问题建议采用DOM4J;如果XML文档较小则建议采用JDOM;如果需要及时处理而不需要保存数据则考虑SAX