1 DOM
DOM:文档对象模型(Document Object Model)。DOM把XML文档映射成一个倒挂的树。
主要包含元素节点,文本节点,属性节点。
DOM解析包:org.w3c.dom
常用接口 | 常用方法 | 说明 |
Document:表示整个XML文档 | NodeList getElementsByTagName(String Tag) | 按文档顺序返回文档中指定标记名称的元素集合 |
Element createElement(String tagName) | 创建指定标记名称的元素 | |
Node:该文档树中的单个节点 | NodeList getChildNodes() | 获取该元素的所有子节点,返回值是节点集合 |
Element:XML文档中的一个元素 | String getTagName() | 获取元素名称 |
2 访问DOM节点
2.1 编写XML文件
本文以如下编写的xml文件(手机信息.xml)作为实例:
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<phoneInfo>
<brand name="华为手机">
<type name="华为荣耀" />
<type name="HW123" />
<type name="RY321" />
</brand>
<brand name="小米手机">
<type name="小米10" />
<type name="红米" />
<type name="Rednote" />
</brand>
</phoneInfo>
2.2 DOM解析XML文件步骤
1.创建解析器工厂对象
DocumentBuilderFactory dbf=DocumentBuilderFactory.newInstance()
2.使用解析器工厂对象创建解析器对象
DocumentBuilder db=dbf.newDocumentBuilder()
3.使用解析器对象指定XML文件创建Document对象
Document document=db.parse("xxx.xml")
4.以Document对象为起点操作DOM树
// 创建解析器工厂对象
// DocumentBuilderFactory是抽象类,通过newInstance()静态方法获取DocumentBuilderFactory的一个引用
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
// 创建解析器对象
try {
DocumentBuilder db = dbf.newDocumentBuilder();
// 创建Document对象,parse()方法:将指定XML文件转换为DOM树
Document document = db.parse("手机信息.xml");
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (SAXException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
2.3 显示xml文件内容
//查询XML文件,即显示XML文件内容的方法
public void printInfo(){
//getElementsByTagName("brand"):获取XML文件中所有的brand元素节点,brand元素节点可能不止一个,返回值是NodeList集合
NodeList brands=document.getElementsByTagName("brand");
//遍历brands集合
for (int i = 0; i < brands.getLength(); i++) {
//获取brands集合元素,返回值Node节点类型
Node node=brands.item(i);
//向下转型:将Node节点类型转换成真正的类型Element元素节点
Element brand=(Element)node;
//getAttribute("属性名"):通过属性名返回属性值
String nameValue=brand.getAttribute("name");
System.out.println(nameValue);
//getChildNodes():获取brand元素节点的子节点,这个子节点可能不止一个,返回的是NodeList集合
NodeList types=brand.getChildNodes();
//遍历子节点types集合
for (int j = 0; j < types.getLength(); j++) {
//获取子节点集合元素
Node typeNode=types.item(j);
//要做判断,确保获取的子节点是元素节点
//getNodeType():判断节点类型,返回一个short值
//ELEMENT_NODE:元素节点静态常量,表示1
if (typeNode.getNodeType()==Element.ELEMENT_NODE) {
Element type=(Element)typeNode;
String typeValue=type.getAttribute("name");
System.out.println("\t"+typeValue);
}
}
}
}
2.4 保存xml文件
步骤如下:
1.获取TransformerFactory对象
TransformerFactory transformerFactory=TransformerFactory.newInstance()
2.创建Transformer对象
Transformer transformer=transformerFactory.newTransformer()
3.设置编码格式
transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8")
4.创建DOMSource对象
DOMSource domSource=new DOMSource(document)
5.创建StreamResult对象
StreamResult result=new StreamResult(new FileOutputStream(url))
6.将DOM信息保存到指定xml文件中
transformer.transform(domSource, result)
//将数据保存到指定XML文件的方法,需要传递一个路径url参数,表示的是xml文件的路径
public void saveXml(String url){
//TransformerFactory类和Transformer类:用来将DOM数据转换为XML文件
//第一步:创建引用
//创建TransformerFactory对象引用
TransformerFactory transformerFactory=TransformerFactory.newInstance();
try {
//创建Transformer对象引用
Transformer transformer=transformerFactory.newTransformer();
//在转换前先设置编码类型格式
/*
* setOutputProperty(String name, String value):设置编码类型,包括属性、属性值
* OutputKeys:提供可用于设置 Transformer的输出属性
* OutputKeys.ENCODING:静态常量,等于encoding
*/
transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");//encoding="UTF-8"
//第二步:把DOM转换为XML文件:transform(Source xmlSource, Result outputTarget)方法
//DOMSource类是Source接口的实现类,创建指定DOM树
DOMSource domSource=new DOMSource(document);
//StreamResult类是Result接口的实现类,StreamResult(OutputStream)方法:需要传递的参数是字节流
StreamResult result=new StreamResult(new FileOutputStream(url));
//传递的参数是Source类型和Result类型
transformer.transform(domSource, result);
} catch (TransformerConfigurationException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (TransformerException e) {
e.printStackTrace();
}
}
2.5 添加DOM节点
主要用到三个方法:
createElement()方法:创建元素节点
setAttribute(String name,String value)方法:设置属性和属性值
appendChild(Node newChild)方法:添加父子关系
//添加xml文件内容的方法
public void addXml(){
//创建brand节点,createElement():创建元素节点
Element brandElement=document.createElement("brand");
//setAttribute(String name,String value):设置属性名、属性值
brandElement.setAttribute("name", "苹果手机");
//创建type节点
Element typeElement=document.createElement("type");
typeElement.setAttribute("name", "iphone14");
//appendChild(Node newChild):添加父子关系
brandElement.appendChild(typeElement);
//获取第一个元素节点:先获取元素节点集合,再获取一个元素
Element phoneInfoElement=(Element)document.getElementsByTagName("phoneInfo").item(0);
//添加父子关系
phoneInfoElement.appendChild(brandElement);
//添加完毕之后,此时的数据还在内存中,需要进一步保存到XML文件中
saveXml("手机信息.xml");
}
2.6 修改DOM节点
修改主要用到的方法是:setAttribute(String name,String value)
//修改XML文件内容的方法
public void updateXml(){
//获取brand元素节点集合
NodeList brands=document.getElementsByTagName("brand");
//遍历集合
for (int i = 0; i <brands.getLength(); i++) {
//获取brandElement元素节点
Element brandElement=(Element)brands.item(i);
//通过属性名获得brand元素节点属性值
String brandName=brandElement.getAttribute("name");
//做个判断,如果属性值是苹果手机,重新设置属性值
if(brandName.equals("苹果手机")){
brandElement.setAttribute("name", "IPhone");
}
}
//修改好后,需要保存到指定的XML文件中
saveXml("手机信息.xml");
}
2.7 删除DOM节点
删除DOM节点必须通过父节点删除,父节点调用removeChild()方法删除子节点。
//删除XML文件内容的方法
public void deleteXml(){
NodeList brandList=document.getElementsByTagName("brand");
//遍历brandList集合
for (int i = 0; i < brandList.getLength(); i++) {
Element brandElement=(Element)brandList.item(i);
String brandName=brandElement.getAttribute("name");
//如果属性名是IPhone,则删除这个brand节点
if(brandName.equals("IPhone")){
//通过父元素节点移除子节点
brandElement.getParentNode().removeChild(brandElement);
}
}
//删除后需要保存
saveXml("手机信息.xml");
}