XML文件是一种通用的数据交换格式,它的平台无关性,语言无关性,系统无关性,给数据集成与交互带来了极大的方便。基本的解析方式包括DOM解析和SAX解析,具体来说包括DOM解析,SAX解析,DOM4J解析以及JDOM解析,首先来讲下DOM解析的具体实现方式:

1.重要的对象

DocumentBuilderFactory: 创建文档解析器的工厂对象

DocumentBuilder :得到文档解析器对象,由工长对象获取

Document :文档对象

2.解析XML实现方式

XML文件:

<?xml version="1.0" encoding="UTF-8"?>
<world>
<comuntry id="1">
<name>China</name>
<capital>Beijing</capital>
<population>1234</population>
<area>960</area>
</comuntry>
<comuntry id="2">
<name id="">America</name>
<capital>Washington</capital>
<population>234</population>
<area>900</area>
</comuntry>
<comuntry id="3">
<name >Japan</name>
<capital>Tokyo</capital>
<population>234</population>
<area>60</area>
</comuntry>
<comuntry id="4">
<name >Russia</name>
<capital>Moscow</capital>
<population>34</population>
<area>1960</area>
</comuntry>
</world>

3.解析XML实现方式

       1.获得DocumentBuilderFactory 

      2.获得DocumentBuilder

     3.读取文件的输入流

     4.获得文档的根元素调用递归函数进行处理

import java.io.File;
import java.io.FileInputStream;
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.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException; public class DOMParse { /**
* 1.获得DocumentBuilderFactory
* 2.获得DocumentBuilder
* 3.读取文件的输入流
* 4.获得文档的根元素调用递归函数进行处理
* @param args
*/
public static void main(String[] args) { //获得DocumentBuilderFactory
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
try {
//获得DocumentBuilder
DocumentBuilder documentBuilder = factory.newDocumentBuilder();
//读取文件的输入流
InputStream inputStream = new FileInputStream(new File("world.xml"));
//获得文档对象
Document document = documentBuilder.parse(inputStream);
//获得文档的根元素
Element rootElement = document.getDocumentElement();
listChildNodes(rootElement,0);
} catch (ParserConfigurationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SAXException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} } /**
* 递归遍历并打印所有的ElementNode(包括节点的属性)
* 1.首先处理该节点信息
* 2.处理节点的属性信息
* 3.处理子节点(递归方法实现)
* @param node 表示节点对象
* @param level 节点所处的层次(从第一层根节点开始1)
*/
public static void listChildNodes(Node node, int level) {
//只处理ElementNode类型的节点
if(level==0){
System.out.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?> ");
}
if (node.getNodeType() == Node.ELEMENT_NODE) {
boolean hasTextChild = false;
String levelSpace = "";
for (int i = 0; i < level; i++) {
levelSpace += " ";
}
//先打印ElementNode的开始标签
System.out.print(levelSpace + "<" + node.getNodeName()
+ (node.hasAttributes() ? " " : ">"));// 有属性的话节点的开始标签后面的尖括号">"就留待属性打印完再打印
if (node.hasAttributes()) {// 遍历打印节点的所有属性
NamedNodeMap namedNodeMap = node.getAttributes();
for (int i = 0; i < namedNodeMap.getLength(); i++) {
System.out.print(namedNodeMap.item(i).getNodeName()
+ "=\""// 字符串里含双引号要用到转义字符\
+ namedNodeMap.item(i).getNodeValue() + "\""
+ (i == (namedNodeMap.getLength() - 1) ? "" : " "));// 不是最后一个属性的话属性之间要留空隙
}
System.out.print(">");// 开始标签里的属性全部打印完加上尖括号">"
}
// 该ElementNode包含子节点时候的处理
if (node.hasChildNodes()) {
level++;// 有下一级子节点,层次加1,新的层次表示的是这个子节点的层次(递归调用时传给了它)
// 获得所有的子节点列表
NodeList nodelist = node.getChildNodes();
// 循环遍历取到所有的子节点
for (int i = 0; i < nodelist.getLength(); i++) {
//子节点为TextNode类型,并且包含的文本内容有效
if (nodelist.item(i).getNodeType() == Node.TEXT_NODE
&& (!nodelist.item(i).getTextContent().matches("\\s+"))) {// 用正则选取内容包含非空格的有效字符的文本节点
hasTextChild = true;// 该ElementNode的一级子节点是存在有效字符的文本节点
System.out.print(nodelist.item(i).getTextContent());// 在开始标签后面添加文本内容
//子节点是正常的ElementNode的处理
} else if (nodelist.item(i).getNodeType() == Node.ELEMENT_NODE) {
System.out.println();
// 递归调用方法 - 以遍历该节点下面所有的子节点
listChildNodes(nodelist.item(i), level);// level表示该节点处于第几个层次(相应空格)
}
}
level--;// 遍历完所有的子节点,层次变量随子节点的层数,依次递减,回归到该节点本身的层次
// level++ 和 level--对于该节点的子节点影响的是子节点的初值
}
//打印元素的结束标签.如果它的第一个一级子节点是有效文本的话,文本和结束标签添加到开始标签后面,
//层次什么的就作废用不上了,否则,才按层次打印结束标签.
System.out.print(((hasTextChild) ? "" : "\n" + levelSpace) + "</"+ node.getNodeName() + ">");
}
}
}

4.大功告成,这就是通过DOM方式实现了XML文件的解析,需要注意的地方就是那个递归调用函数,这个事实现动态解析的关键。用过知道了XML文件的内容,可以讲解析出来的具体对象封装起来,以便入库或者其他用处。有机会好好分享下。

XML文件解析之DOM解析的更多相关文章

  1. 解析XML文件之使用DOM解析器

    在前面的文章中.介绍了使用SAX解析器对XML文件进行解析.SAX解析器的长处就是占用内存小.这篇文章主要介绍使用DOM解析器对XML文件进行解析. DOM解析器的长处可能是理解起来比較的直观,当然, ...

  2. xml文件的生成与解析

    生成方法一:同事StringBuffer类对xml文件格式解析写入 package com.steel_rocky.xml; import android.app.Activity; import a ...

  3. XML解析之DOM解析技术案例

    Java代码: package com.xushouwei.xml; import java.io.File; import javax.xml.parsers.DocumentBuilder; im ...

  4. xml的SAX解析和dom解析的区别

    一,区别 DOM解析 SAX解析 原理: 一次性加载xml文档,不适合大容量的文件读取 原理: 加载一点,读取一点,处理一点.适合大容量文件的读取 DOM解析可以任意进行增删改成 SAX解析只能读取 ...

  5. 2.1 使用JAXP 对 xml文档进行DOM解析

    //使用 jaxp 对xml文档进行dom解析 public class Demo2 { //必要步骤 @Test public void test() throws Exception { //1. ...

  6. Java---XML的解析(1)-DOM解析

    本章只讲DOM解析.接下来还会学习Dom4j和StAX 解析技术 DOM解析: DOM解析一次将所有的元素全部加载到内存中:如有以下XML文档: <user> <name>Ja ...

  7. Java是如何解析xml文件的(DOM)

    Java解析xml文件 在Java程序中读取xml文件的过程也称为"解析xml文件": 解析的目的: 获取 节点名和节点值 获取 属性名.属性值. 四中解析方式: DOM SAX ...

  8. android解析xml文件方法之一-----DOM

    Hello.xml文件 <dict num="219" id="219" name="219"> <key>hell ...

  9. XML概念定义以及如何定义xml文件编写约束条件java解析xml DTD XML Schema JAXP java xml解析 dom4j 解析 xpath dom sax

    本文主要涉及:xml概念描述,xml的约束文件,dtd,xsd文件的定义使用,如何在xml中引用xsd文件,如何使用java解析xml,解析xml方式dom sax,dom4j解析xml文件 XML来 ...

随机推荐

  1. Spark2.x学习笔记:5、Spark On YARN模式

    https://blog.csdn.net/chengyuqiang/article/details/77864246

  2. Spring Cloud(8):日志及分布式跟踪(Sleuth&Zipkin)

    简介 在微服务架构中,项目中前端发起一个请求,后端可能跨几个服务调用才能完成这个请求.如果系统越来越庞大,服务之间的调用与被调用关系就会变得很复杂,那么这时候我们需要分析具体哪一个服务出问题了就会显得 ...

  3. MySQL创建触发器样例

    # init DROP TABLE IF EXISTS students; DROP TABLE IF EXISTS class; # 创建测试用的班级表 CREATE TABLE class ( c ...

  4. sqlserver如何创建链接服务器

    遇到下列问题: 线上服务器A,中转服务器B,本地服务器C 数据在A上面,想在B上面操作类似 select * from [A].[database].table这样的SQL,不用去链接服务器,直接把处 ...

  5. 动态绑定easyui datagrid列名

    根据实时数据在同一个DataGrid中显示不同字段,本身easyui并没有支持动态绑定列名,只有show属性显示或隐藏某字段.今天在网上看到直接修改easyui类库动态绑定列名的方法,废话不多说直接借 ...

  6. 无缝轮播 css3

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  7. linux下的进程间通信之消息队列

    概念: 进程彼此之间可以通过IPC消息进行通信.进程产生的每条消息都被发送到一个IPC消息队列中,这条消息一直存放在队列中,直到另一个进程将其读走为止. 优点:可以通过发送消息来几乎完全避免命名管道的 ...

  8. Flutter运行报错 `kernel_snapshot for errors` 解决方案

    Flutter运行报错 `flutter kernel_snapshot for errors`解决方案 当你Flutter项目删除了dart文件如果遇到 target:kernel_snapshot ...

  9. leetcode1140 Stone Game II

    思路: dp,用记忆化搜索比较好实现. 实现: class Solution { public: int dfs(vector<int>& sum, int cur, int M, ...

  10. 【ARM-Linux开发】Rico Board上编译USB WiFi RT3070驱动

    1.附件中提供了RT3070驱动源码包DPO_RT5572_LinuxSTA_2.6.1.3_20121022.tar.gz和编译好的驱动,这里选择使用taget_file.tar.gz中已经编译好的 ...