什么是 XML?

  • XML 指可扩展标记语言(EXtensible Markup Language)
  • XML 是一种标记语言,很类似 HTML
  • XML 的设计宗旨是传输数据,而非显示数据
  • XML 标签没有被预定义。您需要自行定义标签。
  • XML 被设计为具有自我描述性
  • XML 是 W3C 的推荐标准

对于xml文件,没有被定义好的标签,所有的标签都是用户自己定义,在读取解析的时候,根据标签可以获得想要的值

解析xml文件一共有四种方式,分别是:

  1. DOM
  2. SAX
  3. JDOM
  4. DOM4J

下面详细的介绍这几种方式:

一、DOM(Document Object Model)

Dom解析是将xml文件全部载入,组装成一颗DOM树(树状结构),然后通过节点以及节点之间的关系来解析xml文件,下面结合这个xml文件来进行dom解析。由于DOM这种在加载的时候需要把文件全部加载进内存才可以进行解析的方式,也带来了问题,在xml文件小的情况下可以使用,当一个xml文件相当大的时候,对计算机资源的消耗也是一个不小的开销

xml文件:

<school>
<student>
<no>1001</no>
<name>小明</name>
<score>20</score>
</student>
<student>
<no>1002</no>
<name>小红</name>
<score>80</score>
</student>
</school>

实例:

package demo_xml;

import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException; import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import java.io.IOException; public class Dom {
public static void main(String[] args) {
try {
//创建解析器
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
//把xml文件加载进内存
Document document = db.parse("E:\\IntelliJ IDEA\\jvm\\src\\test.xml");
//获取文件中的根节点
NodeList root = document.getChildNodes();
for (int i = 0; i < root.getLength(); i++) {
Node childNodes = root.item(i);
//通过根节点获取子节点
NodeList childNodes1 = childNodes.getChildNodes();
for (int j = 0; j < childNodes1.getLength(); j++) {
Node node = childNodes1.item(j);
//获取子节点的子节点
NodeList value = node.getChildNodes();
//遍历各个节点的属性值
for (int k = 0; k < value.getLength(); k++) {
if(value.item(k).getNodeName() != "#text") {
System.out.println(value.item(k).getNodeName()
+ ":" + value.item(k).getTextContent());
}
} System.out.println();
}
}
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (SAXException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}

二、SAX(Simple API for XML)

sax这种解析方式在官方的解释是类似于流媒体的方式。我们可以简单的总结为,sax方式可以做到一边扫面文档,一边解析文档,不用把文件加载到内存中,相比于DOM解析方式,SAX方式对于大型的文件是一种很好的解决办法,减少了对内存的消耗。还有就是SAX解析方式是一种基于事件的方式,在解析xml文件的时候就是触发了一系列的事件,当遇到用户给定的标签的时候,会停止解析,这样在时间和空间上都是优于DOM解析的(DOM解析需要把文档全部加载进内存才能开始解析)

要使用SAX解析首先要创建触发器这个类,要创建这个类首先需要继承DefaultHandler,重写方法

xml文件被SAX解析器载入,由于SAX解析是按照xml文件的顺序来解析,当最开始读取xml文档的时候,会调用startDocument()方法,当读入<school>的时候,由于它是个ElementNode,所以会调用startElement(String uri, String localName, String qName, Attributes attributes) 方法,其中第二个参数就是节点的名称,注意:由于有些环境不一样,有时候第二个参数有可能为空,所以可以使用第三个参数,因此在解析前,先调用一下看哪个参数能用,第4个参数是这个节点的属性。这里我们不需要这个节点,所以从<student>这个节点开始,当读入时,调用startElement(....)方法,然后在no标签的地方会调用characters(char[]
ch, int start, int length)方法,Sax解析器会把它认为是一个TextNode。但是这个空白不是我们想要的数据,我们是想要<no>节点下的文本信息。这就要定义一个记录当上一节点的名称的TAG,在characters(.....)方法中,判断当前节点是不是name,是再取值,才能取到值

代码:

package demo_xml;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler; import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream; public class Sax {
public static void parserXml(String fileName) {
SAXParserFactory saxfac = SAXParserFactory.newInstance(); try {
SAXParser saxparser = saxfac.newSAXParser();
InputStream is = new FileInputStream(fileName);
saxparser.parse(is, new MySaxHandler());
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (SAXException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
} public static void main(String[] args) {
Sax.parserXml("E:\\IntelliJ IDEA\\jvm\\src\\test.xml");
}
}
class MySaxHandler extends DefaultHandler {
boolean hasAttribute = false;
Attributes attributes = null; @Override
public void startDocument() throws SAXException {
System.out.println("文档解析");
} @Override
public void endDocument() throws SAXException {
System.out.println("文档结束");
} @Override
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
if (qName.equals("users")) {
return;
}
if (qName.equals("user")) {
return;
}
if (attributes.getLength() > 0) {
this.attributes = attributes;
this.hasAttribute = true;
}
} @Override
public void endElement(String uri, String localName, String qName)
throws SAXException {
if (hasAttribute && (attributes != null)) {
for (int i = 0; i < attributes.getLength(); i++) {
System.out.print(attributes.getQName(0) + ":"
+ attributes.getValue(0));
}
}
} @Override
public void characters(char[] ch, int start, int length)
throws SAXException {
System.out.print(new String(ch, start, length));
}
}

三、JDOM(Java-based Document Object Model)

JDOM也是将xml文件构建成一个树状结构,实现解析,所以代码和DOM很像,但是 JDOM自身不包含解析器。它通常使用SAX2解析器来解析和验证输入XML文档,所以可以说JDOM是DOM和SAX的一个结合体也差不多,把SAX和DOM的功能有效地结合起来。实现了解析xml文档的功能。在代码中我们可以看到SAX和DOM解析代码的片段

package demo_xml;

import org.jdom.Document;
import org.jdom.Element;
import org.jdom.input.SAXBuilder; import java.util.List; public class Jdom {
public static void main(String[] args) throws Exception {
//构建加载器,加载xml文档
SAXBuilder builder = new SAXBuilder();
Document document = builder.build("E:\\IntelliJ IDEA\\jvm\\src\\test.xml");
//获取根节点
Element root = document.getRootElement();
//通过根节点获取子节点的集合
List childList = root.getChildren("student");
//遍历集合
for (int i = 0; i < childList.size(); i++) {
Element childs = (Element) childList.get(i);
//通过上一级节点获取子节点
List child = childs.getChildren();
for (int j = 0; j < child.size(); j++) {
System.out.println(((Element) child.get(j)).getName()
+ ":" + ((Element) child.get(j)).getValue());
}
System.out.println();
}
}
}

四、DOM4J(Document Object Model for Java)

DOM4J是目前使用最广泛的,hibernate框架使用的解析方式就是DOM4J,DOM4J使用接口和抽象基本类方法,在代码上也容易理解(在使用DOM4J时需要下载jar包)

package demo_xml;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader; import java.io.File;
import java.net.MalformedURLException;
import java.util.Iterator; public class Dom4j {
public static void main(String[] args) {
//加载解析器
File inputXml = new File("E:\\IntelliJ IDEA\\jvm\\src\\test.xml");
SAXReader saxReader = new SAXReader();
try {
//获取文档内容
Document document = saxReader.read(inputXml);
//获取根节点
Element root = document.getRootElement();
for (Iterator i = root.elementIterator(); i.hasNext();) {
Element childList = (Element) i.next();
for (Iterator j = childList.elementIterator(); j.hasNext();) {
Element node = (Element) j.next();
System.out.println(node.getName() + ":" + node.getText());
}
System.out.println();
}
} catch (DocumentException e) {
System.out.println(e.getMessage());
} catch (MalformedURLException e) {
e.printStackTrace();
}
}
}

解析xml文件的四种方式的更多相关文章

  1. java读取XML文件的四种方式

    java读取XML文件的四种方式 Xml代码 <?xml version="1.0" encoding="GB2312"?> <RESULT& ...

  2. 解析Xml文件的三种方式及其特点

    解析Xml文件的三种方式 1.Sax解析(simple api  for xml) 使用流式处理的方式,它并不记录所读内容的相关信息.它是一种以事件为驱动的XML API,解析速度快,占用内存少.使用 ...

  3. 解析XML文件的几种方式及其比较

    解析xml文件目前比较流行的主要有四种方式: 1. DOM(Document Object Model)它把整个XML文档当成一个对象加载到内  存,不管文档有多大.它一般处理小文件 2.SAX(Si ...

  4. 解析Xml文件的三种方式

    1.Sax解析(simple api  for xml) 使用流式处理的方式,它并不记录所读内容的相关信息.它是一种以事件为驱动的XML API,解析速度快,占用内存少.使用回调函数来实现. clas ...

  5. 解析XML文件的几种常见操作方法—DOM/SAX/DOM4j

    解析XML文件的几种常见操作方法—DOM/SAX/DOM4j 一直想学点什么东西,有些浮躁,努力使自己静下心来看点东西,哪怕是回顾一下知识.看到了xml解析,目前我还没用到过.但多了解一下,加深点记忆 ...

  6. 解析xml文件的几种技术与Dom4j与sax之间的对比

    一.解析xml文件的几种技术:dom4j.sax.jaxb.jdom.dom 1.dom4j dom4j是一个Java的XML API,类似于jdom,用来读写XML文件的.dom4j是一个非常优秀的 ...

  7. linux创建文件的四种方式(其实是两种,强行4种)

    linux创建文件的四种方式: 1.vi newfilename->i->编辑文件->ESC->:wq! 2.touch newfilename 3.cp sourcePath ...

  8. linux服务器之间传输文件的四种方式

    linux文件传输在内网渗透中至关重要,所以我在此总结一下几种Linux服务器之间传输文件的四种方式 1. scp [优点]简单方便,安全可靠:支持限速参数[缺点]不支持排除目录[用法]scp就是se ...

  9. PHP读写XML文件的四种方法

    PHP对XML文件进行读写操作的方法一共有四种,分别是:字符串方式直接读写.DOMDocument读写. XMLWrite写和XMLReader读.SimpleXML读写,本文将依次对这四种方法进行介 ...

随机推荐

  1. Git创建本地分支并推送到远程github仓库

  2. 关于chrom开发者工具priview和respons 数据内容不一致问题

    在昨天晚上2017年8月24日,深夜升级的时候发现你了一个问题:简单的把问题描述一下:新增的一个付款单中的金额为最大值9999999999999999 ,但是保存后返回来的却是100000000000 ...

  3. python函数式编程之装饰器(二)

    以前用装饰器,都是定义好了装饰器后,使用@装饰器名的方法写入被装饰函数的正上方 在这里,定义的装饰器都是没有参数的 在定义装饰器的函数的时候,没有在括号里定义参数,这就叫做无参装饰器 既然有无参装饰器 ...

  4. Servlet中forward和redirect的区别(转)

    forward方式:request.getRequestDispatcher("/somePage.jsp").forwardrequest, response);     red ...

  5. R+大地图时代︱ leaflet/leafletCN 动态、交互式绘制地图(遍地代码图)

    好久没有学习R的新包了,甚是想念啊! 昨天.今天看到两个极好.不得不学的packages+早上被AWS的服务器整得郁闷ing-于是就来点颜色看看~ 本篇受Lchiffon老师的github启发,对两个 ...

  6. ARM开发软件ADS教程

    ARM开发软件ADS教程 ADS(ARM Developer Suite)是ARM公司推出ARM集成开发环境,操作简单方便,获得广大开发人员的青睐.下面使用ADS v1.2做一个实例教程,帮助大家学会 ...

  7. Android开发中用到的第三方框架汇总

    最近上网搜索了一些框架资料,整理了以下常用框架,希望在项目中有所帮助. 1.网络请求框架 android-async-http 该网络框架的介绍文章地址:http://www.cnblogs.com/ ...

  8. Java获取某年某周的第一天

    Java获取某年某周的第一天 1.设计源码 FirstDayOfWeek.java: /** * @Title:FirstDayOfWeek.java * @Package:com.you.freem ...

  9. LeetCode 456. 132 Pattern

    问题描述 给一组数,判断这组数中是否含有132 pattern. 132 pattern: i < j < k, 且 ai < ak < aj 第一种解法 使用栈来保存候选的子 ...

  10. RobotFramework下的http接口自动化Follow Response关键字的使用

    Follow Response 关键字用于处理http中的重定向请求,常见的http 重定向请求包含http code为301和302 两种重定向请求,代表着某个URL地址发生了转移. http co ...