XML文件解析之DOM解析
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解析的更多相关文章
- 解析XML文件之使用DOM解析器
在前面的文章中.介绍了使用SAX解析器对XML文件进行解析.SAX解析器的长处就是占用内存小.这篇文章主要介绍使用DOM解析器对XML文件进行解析. DOM解析器的长处可能是理解起来比較的直观,当然, ...
- xml文件的生成与解析
生成方法一:同事StringBuffer类对xml文件格式解析写入 package com.steel_rocky.xml; import android.app.Activity; import a ...
- XML解析之DOM解析技术案例
Java代码: package com.xushouwei.xml; import java.io.File; import javax.xml.parsers.DocumentBuilder; im ...
- xml的SAX解析和dom解析的区别
一,区别 DOM解析 SAX解析 原理: 一次性加载xml文档,不适合大容量的文件读取 原理: 加载一点,读取一点,处理一点.适合大容量文件的读取 DOM解析可以任意进行增删改成 SAX解析只能读取 ...
- 2.1 使用JAXP 对 xml文档进行DOM解析
//使用 jaxp 对xml文档进行dom解析 public class Demo2 { //必要步骤 @Test public void test() throws Exception { //1. ...
- Java---XML的解析(1)-DOM解析
本章只讲DOM解析.接下来还会学习Dom4j和StAX 解析技术 DOM解析: DOM解析一次将所有的元素全部加载到内存中:如有以下XML文档: <user> <name>Ja ...
- Java是如何解析xml文件的(DOM)
Java解析xml文件 在Java程序中读取xml文件的过程也称为"解析xml文件": 解析的目的: 获取 节点名和节点值 获取 属性名.属性值. 四中解析方式: DOM SAX ...
- android解析xml文件方法之一-----DOM
Hello.xml文件 <dict num="219" id="219" name="219"> <key>hell ...
- 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来 ...
随机推荐
- Mysql主从复制(重置版)
MySQL Replication是Mysql自带的一种功能,可以实现将数据从一台数据库服务器(master)复制到一台或多台数据库服务器(slave),默认情况下属于异步复制,无需维持长连接.通过配 ...
- Mysql常见索引介绍
索引是一种特殊的文件,包含了对数据表中所有记录的引用指针.InnoDB引擎的数据库,其上的索引是表空间的一个组成部分. (1).索引的优缺点 优点:加快搜索速度,减少查询时间 缺点:索引是以文件的形式 ...
- 单例模式-java
/** * The MIT License * Copyright (c) 2014-2016 Ilkka Seppälä * <p> * Permission is hereby gra ...
- laravel服务提供者类说明
IoC 是将内部设计的类交给系统去控制,但是有些类在初始化的时候,需要制定特定的参数,或者当你需要将实现类绑定到某个接口,这时候就必须对这些依赖进行配置,系统才能正确解析并引用. register 而 ...
- 【Leetcode_easy】599. Minimum Index Sum of Two Lists
problem 599. Minimum Index Sum of Two Lists 题意:给出两个字符串数组,找到坐标位置之和最小的相同的字符串. 计算两个的坐标之和,如果与最小坐标和sum相同, ...
- css 命名规范参考[转]
命名空间 另外最好的实践就是当命名你的类名的时候,使用命名空间前缀来进行分类.这些前缀会在你的命名前添加一组字符,但是这个值能立刻标记每一个类的目的,在你看 HTML 或者样式的时候是很需要的.我使用 ...
- Vue + GraphQL初试
基本用法 GraphQL概述 GraphQL基本语法特性 GraphQL类型系统 GraphQL类型系统内置基础类型 GraphQL类型系统内置修饰符 GraphQL工作原理 GraphQL执行过程 ...
- OpenGL学习笔记 之二 (色彩相关)
参考: http://www.cnblogs.com/FredCong/archive/2012/10/13/2722893.html 使用RGB #include <glut.h> #i ...
- C# 自定义特性(Attribute)详解
什么是特性 特性的定义:公共语言运行时允许添加类似关键字的描述声明,叫做attribute,它对程序中的元素进行标注,如类型.字段.方法.和属性等.attribute和.NetFramework文件的 ...
- Vue 设置style样式
1.直接添加行内样式 2.通过绑定设置style样式 3.将vue的属性设置为样式 4将多个vue属性设置为样式 <div id="box"> <!--直接添加样 ...