Dom4j工具

使用步骤:

1)导入dom4j的核心包。 dom4j-1.6.1.jar

2)编写Dom4j读取xml文件代码

1,Domj4读取xml文件

,准备工作:读取整个文档并获取根节点

//获取document

SAXReader reader = new SAXReader();

Document document = reader.read(new File("src/MyXml.xml"));

//获取根节点

Element rootElement = document.getRootElement();

节点:

Iterator  Element.nodeIterator();  //获取当前标签节点下的所有子节点

标签:

Element  Document.getRootElement();  //获取xml文档的根标签

Element   ELement.element("标签名") //指定名称的第一个子标签

Iterator<Element> Element.elementIterator();//获取所有子标签

List<Element> Element.elements(); //获取所有子标签

  Iterator<Element> Element.elementIterator("标签名");// 指定名称的所有子标签

  List<Element> Element.elements("标签名"); //指定名称的所有子标签

属性:

  String   Element.attributeValue("属性名") //获取指定名称的属性值

  Attribute Element.attribute("属性名");//获取指定名称的属性对象

  Attribute.getName()  //获取属性名称

  Attibute.getValue()  //获取属性值

  List<Attribute>         Element.attributes();  //获取所有属性对象

  Iterator<Attribute> Element.attibuteIterator(); //获取所有属性对象

文本:

Element.getText();  //获取当前标签的文本

  Element.getTextTrim()//获取当前标签的文本,不包含空格

   Element.elementText("标签名") //获取当前标签的指定名称的子标签的文本内容

例子:

/**
* 读取xml文件内容
*
* 读取核心--获取document对象
* SAXReader reader = new SAXReader();
Document document = reader.read(
File/URL/InputStream/InputSource/Reader object);
*
* 1.获取根节点(标签) document.getRootElement()
*
* 2.获取子节点 element.nodeIterator(),然后通过迭代器获取子节点
*
* 3.获取标签
* 1)获取指定名称的标签 element.element(String elementName);
* 2)获取当前标签下的指定名称的子标签集合--两种方法获取
* 迭代器接收:element.elementIterator(String elementName)
* List接收:element.elements(String elementName)
* 3)获取当前标签下的所有子标签--两种方法获取(同上)
* 迭代器接收:element.elementIterator()
* List接收:element.elements()
*/
public class Demo { public static void main(String[] args) { } /**
* 获取文档所有Element(标签)节点,并打印
*/
@Test
public void readXML() throws DocumentException {
//读取文档,获取document对象
SAXReader reader = new SAXReader();
Document document = reader.read(new File("src/MyXml.xml"));
//得到根节点
Element rootElement = document.getRootElement();
//获取子节点
getChildrenNodes(rootElement); } //循环获取子节点,并打印其名称
private void getChildrenNodes(Element element) {
//打印节点名字
System.out.println(element.getName()); @SuppressWarnings("unchecked")
Iterator<Node> iter = element.nodeIterator();
while (iter.hasNext()) {
Node node = iter.next(); if (node instanceof Element) {
Element e = (Element) node;
//递归获取所有子节点
getChildrenNodes(e);
}
} } /**
* 获取标签
*/
@Test
public void readXML2() throws DocumentException { //1.读取文档,获取document对象
SAXReader reader = new SAXReader();
Document document = reader.read(new File("src/MyXml.xml")); //2.得到root(根)标签
Element rootElement = document.getRootElement();
System.out.println("根标签:" + rootElement.getName()); //3.获得第一个指定名称的子标签
Element element = rootElement.element("contract");
System.out.println("第一个contact子标签:" + element.getName());
// System.out.println(element.attribute(0).getName() + element.attribute(0).getValue()); //4.获取当前标签下的指定名字的子标签
// @SuppressWarnings("unchecked")
// Iterator<Element> it = rootElement.elementIterator("contract");
// System.out.println("含有\"contract\"的子标签:");
// while (it.hasNext()) {
// System.out.println(it.next().getName());
// }
@SuppressWarnings("unchecked")
List<Element> eList = rootElement.elements("contract");
System.out.println("含有\"contract\"的子标签:");
for (Element e : eList) {
System.out.println(e.getName());
} //5.获取当前标签下的所有子标签
// @SuppressWarnings("unchecked")
// Iterator<Element> iter = element.elementIterator();
// System.out.println("所有子标签:");
// while (iter.hasNext()) {
// Element e = iter.next();
// System.out.println(e.getName());
// }
//elementIterator可以,element.elements()方法也可以做到
@SuppressWarnings("unchecked")
List<Element> elements = rootElement.elements();
Iterator<Element> eIter = elements.iterator();
System.out.println("所有子标签:");
while (eIter.hasNext()) {
System.out.println(eIter.next().getName());
} } /**
* 读取属性节点的信息
* @throws DocumentException
*/
@SuppressWarnings("unchecked")
public void test3() throws DocumentException { //获取整个xml对象节点
SAXReader reader = new SAXReader();
Document document = reader.read(new File("src/MyXml.xml")); //获取根节点
Element contact = document.getRootElement().element("contact"); //获取指定名称的属性
// Attribute attribute = contact.attribute("id");
// System.out.println("通过指定名字获取:\nid:" + attribute.getValue() + "\n");
String value = contact.attributeValue("id");
System.out.println("通过指定名字获取:\nid:" + value + "\n"); //获取所有属性的名称
Iterator<Attribute> aIter = contact.attributeIterator();
System.out.println("获取所有属性:");
while (aIter.hasNext()) {
Attribute a = aIter.next();
System.out.println(a.getName() + ":" +a.getValue());
}
} /**
* 获取文本
* 注意:空格和换行也是文本
* @throws DocumentException
*/
@Test
public void test4() throws DocumentException { //获取整个xml对象节点
SAXReader reader = new SAXReader();
Document document = reader.read(new File("src/MyXml.xml")); //获取根节点
Element contact = document.getRootElement().element("contact"); //打印文本内容
// String text = contact.element("name").getText();
// String text = contact.element("name").getTextTrim();
String text = contact.elementText("name");
String text2 = contact.elementTextTrim("name");
System.out.println("elementText:" + text);
System.out.println("elementTextTrim:" + text2); //空格和换行也是文本,但是getTextTrim可以去掉空格和换行
// String text3 = contact.getText().trim();
String text3 = contact.getTextTrim();
System.out.println(text3);
} }

Dom4j修改xml文档

写出内容到xml文档

XMLWriter writer = new XMLWriter(OutputStream, OutputForamt)

wirter.write(Document);

修改xml文档的API

增加:

DocumentHelper.createDocument()  增加文档

addElement("名称")  增加标签

addAttribute("名称",“值”)  增加属性

修改:

Attribute.setValue("值")  修改属性值

Element.addAtribute("同名的属性名","值")  修改同名的属性值

Element.setText("内容")  修改文本内容

删除

Element.detach();  删除标签

Attribute.detach();  删除属性

例子:

/**
* XML文档的增删改
*
* 1. 增加--文档,注释,标签,属性,文本
* 2. 修改--属性,文本
* 3. 删除--标签,属性
* @author Administrator
*
*/ public class Demo2 { public static void main(String[] args) {
new Demo2().CRUD();
} /**
* 对XML文件进行增删改
*/
public void CRUD() {
//增加
addXML();
//修改
updateXML();
//删除
delFromXML();
} /**
* 增加节标签,属性,文本
*/
public void addXML() {
//创建新文档
Document document = DocumentHelper.createDocument();
//创建注释
document.addComment("学生信息...");
//创建根节点
Element rootElement = document.addElement("Students");
//创建第一个子节点
Element child = rootElement.addElement("childElement")
.addAttribute("id", "1");
child.addElement("name").addText("张三");
child.addElement("sex").addText("男");
child.addElement("grade").addText("计算机一班");
child.addElement("address").setText("广州天河");
//第二个子节点
Element child2 = rootElement.addElement("childElement")
.addAttribute("id", "2");
child2.addElement("name").addText("李四");
child2.addElement("sex").addText("女");
child2.addElement("grade").addText("计算机二班");
child2.addElement("address").setText("广州深圳"); //覆盖写入文档
writeToXML(document);
} /**
* 修改属性,文本
*/
@SuppressWarnings("unchecked")
public void updateXML() {
//获取document对象
Document document = getDocumentFromXML();
//修改属性节点,把id为1的改成01
Element rootElement = document.getRootElement();
Iterator<Element> eIter = rootElement.elementIterator();
while (eIter.hasNext()) {
Element stu = eIter.next();
Attribute a = stu.attribute("id");
if (a != null && a.getValue().equals("1")) {
// stu.addAttribute("id", "01"); 方式一:通过添加相同名字的属性来修改
a.setValue("01");
// System.out.println("00000");
} if (a != null && a.getValue().equals("2")) {
Iterator<Element> iter = stu.elementIterator();
while (iter.hasNext()) {
Element element = iter.next();
if (element.getName().equals("name")) {
element.setText("王丽");
}
}
}
} writeToXML(document);
} /**
* 删除属性,标签
*/
@SuppressWarnings("unchecked")
public void delFromXML() { Document document = getDocumentFromXML(); Element rootElement = document.getRootElement();
//删除属性节点,其id=2
Iterator<Element> eIter = rootElement.elementIterator();
while (eIter.hasNext()) {
Element stu = eIter.next();
Attribute a = stu.attribute("id");
if (a != null && a.getValue().equals("2")) {
a.detach();
//删除标签
stu.detach();
} } writeToXML(document); } /**
* 写入文档
*/
public void writeToXML(Document document) { try {
//输出流
OutputStream out = new FileOutputStream("src/MyXML.xml");
//输出格式
OutputFormat format = OutputFormat.createPrettyPrint();
format.setEncoding("UTF-8");
//创建XMLWriter对象
XMLWriter writer = new XMLWriter(out, format);
writer.write(document); //关闭流
out.close();
writer.close(); } catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} } /**
* 读取文档
*/
public Document getDocumentFromXML() {
try {
SAXReader reader = new SAXReader();
return reader.read(new File("src/MyXml.xml")); } catch (DocumentException e) {
e.printStackTrace();
System.exit(0);
}
return null;
}
}

xPath技术

引入

问题:当使用dom4j查询比较深的层次结构的节点(标签,属性,文本),比较麻烦!!!

xPath作用

主要是用于快速获取所需的节点对象。

在dom4j中如何使用xPath技术

1)导入xPath支持jar包 。  jaxen-1.1-beta-6.jar

2)使用xpath方法

List<Node>  selectNodes("xpath表达式");   查询多个节点对象

Node       selectSingleNode("xpath表达式");  查询一个节点对象

xPath语法

/      绝对路径      表示从xml的根位置开始或子元素(一个层次结构)

//     相对路径       表示不分任何层次结构的选择元素。

*      通配符         表示匹配所有元素

[]      条件           表示选择什么条件下的元素

@     属性            表示选择属性节点

and     关系          表示条件的与关系(等价于&&)

text()    文本           表示选择文本内容

例子:

public class Demo2 {

    @SuppressWarnings("unchecked")
public static void main(String[] args) throws DocumentException { //获取整个xml对象节点
Document document = new SAXReader().read(new File("src/MyXml.xml")); String xPath; //定义查找规则
xPath = "/contactList";//根节点 xPath = "//contact";//子节点的两种形式
xPath = "//contactList/*"; xPath = "//contactList/*/name";//绝对路径和相对论路径查找标签
xPath = "//contactList//name"; xPath = "//contact[@id]";//获取contact节点
xPath = "//@id";//获取名字为id的属性
xPath = "//*[not(@*)]";//获取没有属性的节点
xPath = "//contact/name[text()='李四']";//获取名字为李四的节点
xPath = "//contact/name[normalize-space(text())='董十三']";//忽略文本前后的空格,获取名字为董十三的节点
xPath = "//contact/qq[string-length(text())>7]";//获取QQ号大于七位的标签
xPath = "//contact/*[string-length(text())>7]";//获取文本大于七位的标签
xPath = "//contact/*[string-length(name())>4]";//获取标签名大于四位的标签 List<Node> nList = document.selectNodes(xPath);
for (Node node : nList) {
System.out.println(node);
}
} }

SAX解析

4.1回顾DOM解析

DOM解析原理:一次性把xml文档加载进内存,然后在内存中构建Document树。

对内存要求比较要。

缺点: 不适合读取大容量的xml文件,容易导致内存溢出。

SAX解析原理: 加载一点,读取一点,处理一点。对内存要求比较低。

SAX解析工具

SAX解析工具-  Sun公司提供的。内置在jdk中。org.xml.sax.*

核心的API:

SAXParser类: 用于读取和解析xml文件对象

parse(File f, DefaultHandler dh)方法: 解析xml文件

参数一: File:表示 读取的xml文件。

参数二: DefaultHandler: SAX事件处理程序。使用DefaultHandler的子类

1.创建SAXParser对象

SAXParser parser=SAXParserFactory.newInstance().newSAXParser();

2.调用parse方法

parser.parse(new File("./src/contact.xml"), new MyDefaultHandler());

[一个类继承class 类名(extends DefaultHandler)  在调用是创建传进去

DefaultHandler类的API:

void startDocument()  :  在读到文档开始时调用

void endDocument()  :在读到文档结束时调用

void startElement(String uri, String localName, String qName, Attributes attributes)  :读到开始标签时调用

void endElement(String uri, String localName, String qName)   :读到结束标签时调用

void characters(char[] ch, int start, int length)  : 读到文本内容时调用

例子:

 /*
* 需求:把xml文档完整的打印出来
*/
public class Demo2 { public static void main(String[] args) throws Exception { //SAXParser对象
SAXParser saxParser = SAXParserFactory.newInstance().newSAXParser();
MyDefaultHandler2 dh = new MyDefaultHandler2();
saxParser.parse(new File("src/MyXml.xml"), dh);
System.out.println(dh.getContent());
} } class MyDefaultHandler2 extends DefaultHandler { //读出内容
private StringBuffer sb = new StringBuffer(1000);
//返回内容结果
public String getContent() {
return sb.toString();
} @Override
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
sb.append("<" + qName); for (int i = 0, len = attributes.getLength(); i < len; i++) {
sb.append(" " + attributes.getQName(i) + "=\""
+ attributes.getValue(i) + "\"");
} sb.append(">");
} @Override
public void characters(char[] ch, int start, int length)
throws SAXException {
sb.append(new String(ch, start, length));
} @Override
public void endElement(String uri, String localName, String qName)
throws SAXException {
sb.append("</" + qName + ">");
} }

         ============DOM解析    vs   SAX解析              ========

DOM解析

SAX解析

原理: 一次性加载xml文档,不适合大容量的文件读取

原理: 加载一点,读取一点,处理一点。适合大容量文件的读取

DOM解析可以任意进行增删改成

SAX解析只能读取

DOM解析任意读取任何位置的数据,甚至往回读

SAX解析只能从上往下,按顺序读取,不能往回读

DOM解析面向对象的编程方法(Node,Element,Attribute),Java开发者编码比较简单。

SAX解析基于事件的编程方法。java开发编码相对复杂。

解析和操作XML文件的更多相关文章

  1. 无废话Android之android下junit测试框架配置、保存文件到手机内存、android下文件访问的权限、保存文件到SD卡、获取SD卡大小、使用SharedPreferences进行数据存储、使用Pull解析器操作XML文件、android下操作sqlite数据库和事务(2)

    1.android下junit测试框架配置 单元测试需要在手机中进行安装测试 (1).在清单文件中manifest节点下配置如下节点 <instrumentation android:name= ...

  2. JAVA中通过Jaxp操作XML文件基础

    Java中有多种方式操作XML文件,目前讲一讲以SUN公司提供的DocumentBuilderFactory工厂类对象操作XML. 使用XML基本操作就是需要CRUD(增删改查),那么首先通过一个查询 ...

  3. python解析VOC的xml文件并转成自己需要的txt格式

    在进行神经网络训练的时候,自己标注的数据集往往会有数据量不够大以及代表性不强等问题,因此我们会采用开源数据集作为训练,开源数据集往往具有特定的格式,如果我们想将开源数据集为我们所用的话,就需要对其格式 ...

  4. WebAPI调用笔记 ASP.NET CORE 学习之自定义异常处理 MySQL数据库查询优化建议 .NET操作XML文件之泛型集合的序列化与反序列化 Asp.Net Core 轻松学-多线程之Task快速上手 Asp.Net Core 轻松学-多线程之Task(补充)

    WebAPI调用笔记   前言 即时通信项目中初次调用OA接口遇到了一些问题,因为本人从业后几乎一直做CS端项目,一个简单的WebAPI调用居然浪费了不少时间,特此记录. 接口描述 首先说明一下,基于 ...

  5. Asp.Net 操作XML文件的增删改查 利用GridView

    不废话,直接上如何利用Asp.NET操作XML文件,并对其属性进行修改,刚开始的时候,是打算使用JS来控制生成XML文件的,但是最后却是无法创建文件,读取文件则没有使用了 index.aspx 文件 ...

  6. 使用Pull解析器生成XML文件和读取xml文件

    有些时候,我们需要生成一个XML文件,生成XML文件的方法有很多,如:可以只使用一个StringBuilder组拼XML内容,然后把内容写入到文件中:或者使用DOM API生成XML文件,或者也可以使 ...

  7. Java操作XML文件 dom4j 篇

    在项目中,我们很多都用到了xml文件,无论是参数配置还是与其它系统的数据交互.今天就来讲一下Java 中使用dom4j来操作XML文件. 我们需要引入的包: //文件包 import java.io. ...

  8. PHP操作XML文件学习笔记

    原文:PHP操作XML文件学习笔记 XML文件属于标签语言,可以通过自定义标签存储数据,其主要作用也是作为存储数据. 对于XML的操作包括遍历,生成,修改,删除等其他类似的操作.PHP对于XML的操作 ...

  9. Qt之QDomDocument操作xml文件-模拟ini文件存储

    一.背景 不得不说Qt是一个很强大的类库,不管是做项目还是做产品,Qt自身封装的东西就已经非常全面了,我们今天的这篇文章就是模拟了Qt读写ini文件的一个操作,当然是由于一些外力原因,我们决定自己来完 ...

随机推荐

  1. 资料:MVC框架+SQL Server 数据集成引擎

    ylbtech-资料:MVC框架+SQL Server 数据集成引擎 1.返回顶部 1. 功能特点: MVC框架耦合性低视图层和业务层分离,这样就允许更改视图层代码而不用重新编译模型和控制器代码,同样 ...

  2. UML核心元素--分析类

    分析类共有三个:边界类(boundary).控制类(control)和实体类(entity),这些分析类都是类的版型.分析类是跨越需求到设计实现的桥梁. 边界类:从需求向现实的转换过程中,任何两个有交 ...

  3. shell入门-cut命令

    命令:cut 选项:-d:-f  指定第几段由“:(分割符)”分割的段 -c    指定第几个字符 说明:选取命令,选取一段数据中我们想要的,一般是针对每行来分析选取的 [root@wangshaoj ...

  4. [bzoj1568]李超线段树模板题(标志永久化)

    题意:要求在平面直角坐标系下维护两个操作: 1.在平面上加入一条线段.记第i条被插入的线段的标号为i. 2.给定一个数k,询问与直线 x = k相交的线段中,交点最靠上的线段的编号. 解题关键:注意标 ...

  5. Unity添加自定义快捷键——UGUI快捷键

    在Editor下监听按键有以下几种方式: 自定义菜单栏功能: using UnityEngine; using UnityEditor; public static class MyMenuComma ...

  6. URL中#符号的作用

    转自http://blog.sina.com.cn/s/blog_6f9eb2dd0100sk97.html 一.#的涵义 #代表网页中的一个位置.其右面的字符,就是该位置的标识符.比如,       ...

  7. p2341&bzoj1051 受欢迎的牛

    传送门(洛谷) 传送门(bzoj) 题目 每一头牛的愿望就是变成一头最受欢迎的牛.现在有N头牛,给你M对整数(A,B),表示牛A认为牛B受欢迎. 这 种关系是具有传递性的,如果A认为B受欢迎,B认为C ...

  8. Jquery常用标签

    $(this).hide(1000)//隐藏该元素 $(this).show(1000)//显示该元素 $(this).fadeIn(1000)//淡入已隐藏的元素 $(this).fadeOut(1 ...

  9. 如何利用OpenSSL生成证书

    此文已由作者赵斌授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. 一.前言 最近为了测试内容分发网络(Content Delivery Network,简称 CDN)添加的新功 ...

  10. 历届试题_log大侠

    标题:Log大侠     atm参加了速算训练班,经过刻苦修炼,对以2为底的对数算得飞快,人称Log大侠.     一天,Log大侠的好友 drd 有一些整数序列需要变换,Log大侠正好施展法力... ...