1.工具:DOM解析使用的工具:dom4j
2.将dom4j 的jar 包导入eclipse 项目下的方法:
(1)如果是Java项目,在项目下新建一个目录lib,可以使用此目录存放额外需要导入的jar包——>右键“add to build path”,将jar包关联到项目下
(2)如果是web项目,根目录下的“webContent”——>文件夹“WEB INF”——>“lib文件夹”
3.DOM解析的原理:
(1)xml解析引擎在解析xml文件的时候,将当前的xml文件中的每一个标签都封装成了一个对象(标签对象/节点对象)——> 形成树状结构
(2)结构顺序:
Node(节点对象)
Element(标签对象)
Attribute(属性对象)
Text(文本对象)
(3)dom解析的原理图解:
3.使用dom4j工具读取xml文件的方法:
dom4j工具api关于解析xml文件的源码:
public class Foo { public Document parse(URL url) throws DocumentException { SAXReader reader = new SAXReader(); Document document = reader.read(url); return document; } }
(1)创建解析器对象:SAXReader reader = new SAXReader();
(2)读取xml文件,获得xml文档对象:Document doc = reader.read(new File("xml文件")) ;
注:返回的对象是document对象,代表的是当前xml文件的文档信息
1.使用dom4j工具获取xml文件中的每一个标签对象(Element):
(1)获取根节点:文档对象.getRootElement();
(2)通过根节点获取第一个子节点:根节点对象.element(“标签名称”); 注:此方法默认获取第一个子节点
(3)获取所有同名的节点对象:根节点对象.elements(“标签名称”); 注:此方法返回的是一个List集合 List
(4)获取根节点下所有的节点对象:根节点对象.elements();
(5)获取根节点的孙节点对象:根节点对象.element("子节点名称").element("孙节点名称");
注意:获取节点名称的方法:getName();
练习:使用dom4j工具获取xml文件中的标签对象
import java.io.File;
import java.util.List;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
public class Test1 {
public static void main(String[] args) throws Exception{
// 创建xml文件解析器对象SAXReader
Document doc = new SAXReader().read(new File("./src/contact.xml"));
// 获取根节点
Element rootElement = doc.getRootElement();
String rootName = rootElement.getName();
System.out.println(rootName);
System.out.println("----------------");
// 获取根节点下的第一个子标签
Element contactElement = rootElement.element("contact");
System.out.println(contactElement.getName());
System.out.println("----------------");
// 获取根节点下的所有子标签
List list = rootElement.elements();
for(Element e:list){
System.out.println(e.getName());
}
System.out.println("----------------");
// 获取根节点下的所有同名的子标签
List conEleList = rootElement.elements("contact");
for(Element e:conEleList){
System.out.println(e.getName());
}
System.out.println("----------------");
// 获取根节点下的孙节点
Element nameElement = rootElement.element("contact").element("name");
System.out.println(nameElement.getName());
}
}
2.使用dom4j工具获取xml文件节点对象的属性(Attribute)
(1)获取该属性的属性值:标签对象.attributeValue("属性名称");
(2)获取属性对象:Attribute attribute =标签对象.attribute(“属性名称”) ;
获取属性名称:attribute对象.getName();
获取属性值:attribute对象.getValue();
(3)获取一个标签下的所有属性:
List
练习:使用dom4j工具获取标签属性
import java.io.File;
import java.util.List;
import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
public class Test2 {
public static void main(String[] args) throws Exception{
// 创建xml文件解析器对象SAXReader
Document doc = new SAXReader().read(new File("./src/contact.xml"));
// 获取id="001"的属性值
Element conElement = doc.getRootElement().element("contact");
String idValue = conElement.attributeValue("id");
System.out.println(idValue);
System.out.println("----------------");
// 获取id="002"的属性值
List conList = doc.getRootElement().elements("contact");
Element con1 = conList.get(1); //获取第二个contact标签对象
String idValue1 = con1.attributeValue("id");
System.out.println(idValue1);
System.out.println("----------------");
// 通过属性对象的方式:获取第一个contact标签的属性对象
Element conElement0 = doc.getRootElement().element("contact");
Attribute idAttribute = conElement0.attribute("id"); // 获取id属性对象
String name = idAttribute.getName();
String value = idAttribute.getValue();
System.out.println(name+"="+value);
System.out.println("----------------");
// 获取第一个contact标签下的所有属性
List conAttList = doc.getRootElement().element("contact").attributes();
for(Attribute a:conAttList){
System.out.println(a.getName()+"="+a.getValue());
}
}
}
(1)获取节点的文本内容:标签对象.getText();
(2)针对父节点获取子节点的文本内容:父节点对象.elementText(“子节点名称”)
注:xml解析使用dom4j可以把空格和换行当做内容解析出来
练习:使用dom4j工具获取指定标签对象的文本内容
import java.io.File;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
public class Test3 {
public static void main(String[] args) throws Exception{
// 创建xml文件解析器对象SAXReader
Document doc = new SAXReader().read(new File("./src/contact.xml"));
// 方式1:获取第一个contact节点下的name标签的文本内容
Element nameElement = doc.getRootElement().element("contact").element("name");
String nameContent = nameElement.getText();
System.out.println(nameContent);
System.out.println("-------------------");
// 方式2:通过父节点获取子节点标签下的文本内容
Element conElement = doc.getRootElement().element("contact");
String nameContent1 = conElement.elementText("name");
String ageContent = conElement.elementText("age");
String genderContent = conElement.elementText("gender");
String phoneContent = conElement.elementText("phone");
String addressContent = conElement.elementText("address");
System.out.println(nameContent1+"——"+ageContent+"——"+genderContent+"——"+phoneContent+"——"+addressContent);
}
}
1.使用dom4j修改xml文件的方法:
dom4j工具api关于修改xml文件的源码:
public class Foo {
public void write(Document document) throws IOException {
// lets write to a file
XMLWriter writer = new XMLWriter(
new FileWriter( "output.xml" )
);
writer.write( document );
writer.close();
// Pretty print the document to System.out
OutputFormat format = OutputFormat.createPrettyPrint();
writer = new XMLWriter( System.out, format );
writer.write( document );
// Compact format to System.out
format = OutputFormat.createCompactFormat();
writer = new XMLWriter( System.out, format );
writer.write( document );
}
}
2.输出的文件格式:
(1)紧凑格式(没有空格和换行):OutputFormat.createCompactFormat()
(2)漂亮格式(有空格和换行):OutputFormat.createPrettyFormat()
(3)指定编码格式:OutputFormat对象.setE ncoding("utf-8")
(1)读取源xml文件,返回的是一个document对象
(2)创建一个XMLWriter对象,底层是通过基本的流将文件输出到硬盘上
(3)使用XMLWriter中的write方法,将doc对象从内存写到硬盘上覆盖原文件
修改xml文件:
创建一个新的xml文件:
DocumentHelper类createDocument() ;
addElement(“标签名称”);-添加标签元素
addAttribute(“属性名称”,”属性值”)添加该标签的对应的属性
修改文本内容:setText(“指定内容”)
修改属性:获取该标签对象对应的属性对象Attribute setAttributeValue(“属性值”)
使用dom4j工具可以去利用XMLWriter类输出一个新的xml文件,将原来的xml覆盖掉,进行修改操作!
通过SAXReader类获取document文档对象
创建一个输出流对象(OutputStream/FileWriter)
创建一个OutputFormat对象,生成xml文件的一种格式:紧凑格式(没有空格和换行)/漂亮格式(有固定的格式:空格和换行)
OutputFormat对象指定xml文件的编码格式:utf-8
创建XMLWriter对象 XMLWriter(OutputStream out,OutputFormat format) ;
XMLWriter的write(Document doc) ;
释放资源;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;
import org.dom4j.Document;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;
public class Test4 {
public static void main(String[] args) throws Exception{
// 1)读取当前项目下面的conact.xml文件
Document doc = new SAXReader().read(new File("./src/contact.xml")) ;
// 2)创建输出流对象
OutputStream out = new FileOutputStream("E://contact.xml");
// 输出格式
OutputFormat format = OutputFormat.createPrettyPrint();
//指定编码格式
format.setEncoding("utf-8");
// 3)创建XMLWriter对象
XMLWriter writer = new XMLWriter(out,format);
// 4)写入数据
writer.write(doc);
// 5)释放资源
writer.close();
}
}
1.添加:
(1)添加节点:
<1>创建一个新的doc对象:Document doc = DocumentHelper.createDocument() ;
<2>创建一个根节点:doc.addElement("根节点名称") ;
<3>根节点下创建子节点:根节点对象.addElement("子节点名称");
(2)添加属性:
当前节点对象.addAttribute("属性名称","属性值");
(3)添加文本内容:
节点对象.setText("文本内容");
2.修改xml文件:
(1)设置属性值:属性对象.setValue("属性值");
(2)直接设置属性名称和属性值:节点对象.setAttributeValue("属性名称","属性值");
(3)修改文本内容:节点对象.setText("文本内容")
3.删除:
删除分两种:自杀和他杀
(1)自杀:节点对象.detach();
(2)他杀:父节点对象.remove(节点对象);
练习:使用dom4j修改xml文件
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;
import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;
public class Test5 {
public static void main(String[] args) throws Exception {
//add();
//edit();
delete();
}
/*
* 刪除的方法
* */
private static void delete() throws Exception{
//读取原来的xml文件
Document doc = new SAXReader().read(new File("./src/contact.xml")) ;
//通过doc对象获取第一个contact子节点,然后删除这节点
Element conElem = doc.getRootElement().element("contact") ;
// 刪除這個節點(使用父節點刪除)
conElem.getParent().remove(conElem) ;
//删除指定节点对象的属性
Attribute attriId = doc.getRootElement().element("contact").attribute("id") ;
//detach()
attriId.detach() ;
//输出到E盘下
OutputStream out = new FileOutputStream("E:/contact.xml") ;
OutputFormat format = OutputFormat.createPrettyPrint() ;
//设置编码格式
format.setEncoding("utf-8");
//创建XMLWriter对象
XMLWriter writer = new XMLWriter(out, format) ;
writer.write(doc);
writer.close();
}
/*
* 修改的方法
* */
private static void edit() throws Exception {
//读取原来的xml文件
Document doc = new SAXReader().read(new File("./src/contact.xml")) ;
//修改第一个contact标签的属性,前提要获取当前contact标签对象
Element conElem = doc.getRootElement().element("contact") ;
//通过当前conElem对象获取属性对象
Attribute attri = conElem.attribute("id") ;
//设置属性值
attri.setValue("003");
//指定同名的属性,属性值会被覆盖掉
conElem = doc.getRootElement().element("contact") ;
conElem.setAttributeValue("id", "001"); //直接设置属性名称和属性值
//修改文本内容
Element nameElem = conElem.element("name") ;
nameElem.setText("王五");
//输出到E盘下
OutputStream out = new FileOutputStream("E:/contact.xml") ;
OutputFormat format = OutputFormat.createPrettyPrint() ;
//设置编码格式
format.setEncoding("utf-8");
//创建XMLWriter对象
XMLWriter writer = new XMLWriter(out, format) ;
writer.write(doc);
writer.close();
}
/*
* 添加的方法,新建xml文件
* */
private static void add() throws Exception {
//创建一个新的doc对象,Documenthelper
Document doc = DocumentHelper.createDocument() ;
//创建一个根节点
Element rootElem = doc.addElement("contact-list") ;
//在根节点下面创建一个子节点
Element conElem = rootElem.addElement("contact") ;
Element nameElem = conElem.addElement("name") ;
//给nameElem节点对象设置文本内容,节点对象.setText("内容") ;
nameElem.setText("伊卡二弟");
//添加属性
//当前节点对象.addAttribute("属性名称","属性值")
conElem.addAttribute("id", "001") ;
conElem.addAttribute("name", "gaoyuanyuan") ;
conElem.addAttribute("class", "c") ;
//输出到E盘下
OutputStream out = new FileOutputStream("E:/contact.xml") ;
OutputFormat format = OutputFormat.createPrettyPrint() ;
//设置编码格式
format.setEncoding("utf-8");
//创建XMLWriter对象
XMLWriter writer = new XMLWriter(out, format) ;
writer.write(doc);
writer.close();
}
}
三、DOM解析的封装思想
练习:使用dom4j工具将contact.xml文件封装成一个Contact对象(实体对象)
/*
* 使用dom4j工具将contact.xml文件封装成一个Contact对象(实体对象)
* */
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
public class Test6 {
public static void main(String[] args) {
try {
//目标:将contact.xml中的contact标签封装到Cotnact对象中--->保存到这里面
//1)创建SAXReader解析器对象,读取src下面的contact.xml文件
Document doc = new SAXReader().read(new File("./src/contact.xml")) ;
//2)创建一个集合,集合用来存储多个Contact对象
List conList = new ArrayList() ;
//3)使用刚才获取的doc文档对象获取当前xml文件的根节点下所有的contact标签对应的节点对象
List elemList = doc.getRootElement().elements("contact") ;
//非空判断,防止空指针异常
if(elemList != null){
for(Element e :elemList){
//使用封装的思想,创建一个联系人对象
//需要将得到的contact标签的属性,文本内容封装到Contact对象中
Contact con = new Contact() ;
con.setId(e.attributeValue("id")) ;
con.setName(e.elementText("name"));
con.setGender(e.elementText("gender"));
con.setPhone(e.elementText("phone"));
con.setAddress(e.elementText("address"));
//将多个联系人对象存储到集合中
conList.add(con) ;
}
}
//遍历集合
for(Contact con:conList){
System.out.println(con);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
/*
* 聯繫人類
* */
public class Contact {
private String id ;
private String name ;
private String gender ;
private String phone ;
private String email ;
private String address ;
//提供setter/getter方法
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
@Override
public String toString() {
return "Contact [id=" + id + ", name=" + name + ", gender=" + gender
+ ", phone=" + phone + ", email=" + email + ", address="
+ address + "]";
}
}
伊卡尔迪
24
男
123456
阿根廷布宜诺斯艾利斯
汉达诺维奇
29
男
654321
斯洛文尼亚
斯帕莱蒂
54