DOM接口技术
DOM概述
DOM是什么
- Document Object Model 文档对象模型
- DOM是一个与平台无关,语言无关的应用程序接口
- DOM是W3C组织定义并公布的一个规范
DOM作用
- 提供一个统一的XML数据接口
- 应用DOM,可以动态创建文档,遍历文档,添加修改删除文档中的内容
- DOM接口规范提供了一种编写XML代码的方法
DOM的结构
-
DOM把文档表示为节点(Node)对象树
-
节点对象表示文档中XML元素,也代表文档内其他所有内容(比如文本
根元素,处理指令,注释文档类型,实体,实体引用,命名空间等多种对象模型
-
DOM树展示了XML文件提供的信息以及它们之间的关系。
DOM接口
-
Document
-
Node:代表DOM树中的一个节点 。
-
NodeList:表示有顺序关系的一组节点。
-
NamedNodeMap:通过名字来访问节点的集合。
Document接口
- 提供对文档数据访问和操作的入口,提供了创建其他节点对象的方法
Document.doctype => 拿到文档的 DOCTYPE
Document.documentElement => 拿到文档的根节点
node接口
DOM接口的很多接口是从node继承而来的,代表树的一个节点,提供访问DOM树某个元素的内容与信息的途径
node.nodeType => 节点类型
node.nodeName => 节点名称
nodeList接口
提供对节点集合的抽象定义,表示有顺序的集合
例如上述我们用node接口获得孩子节点
NodeList nl = node.childNodes => 获取孩子节点
Node child1 = nl.item(0); => 访问第一个孩子节点
NamedNodeMap
这个接口可以用名字来访问一组节点
例如上述我们用node接口获得node属性
NameNodeMap nnm = node.attributes; => 获得节点属性集合
string value = nnm.getNamedItem("xxx"); => 通过属性名获得某个属性值
DOM对象
- Document
- Element
- Attriubute
- Text
- 集合索引
Document对象
例子:加载XML文档
- 导入java依赖
import java.io.*; //Java基础包,包含各种IO操作
import javax.xml.parsers.*; //XML解析器接口
import org.w3c.dom.*; //XML的DOM实现
- 解析
try {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse(new File("xxx.xml"));
} catch (Exception e) {
}
这个对象有很多属性和方法
注意这些属性都是私有属性,可以通过getxxx访问
例如 childNodes=> getChildNodes()
下面的其他对象也是一样的 (下面没有标粗的代表我觉得没用的
属性/方法 | 描述 |
---|---|
async | 表示xml的下载是否应当被同步处理 |
childNodes | 获得文档的子节点的节点列表 |
doctype | 文档的DTD声明 |
xmlEncoding | 编码方法 |
xmlStandalone | 文档是否为独立的 |
xmlVersion | 返回文档的XML版本 |
createAttribute(name) | 创建一个拥有指定名称的属性节点,返回新的Attr对象 |
createElement(name) | 创建元素节点 |
createTextNode(text) | 创建文本节点 |
getElementsByTagName() | 返回所有具有指定名称的元素节点 |
loadXML(text) | 通过解析XML标签字符串来组成文档 |
normalize() | 去掉xml文档中的空白部分 |
renameNode(node, uri, name) | 重新命名元素或者属性 |
getDocumentElement() | 获得文档的根节点 |
node
一下是node对象的属性
属性 | 描述 |
---|---|
firstChild | 返回节点的首个子节点。 |
lastChild | 返回节点的最后一个子节点。 |
nextSibling | 返回节点之后紧跟的同级节点。 |
nodeType | 返回节点的类型。 |
nodeValue | 设置或返回节点的值,根据其类型。 |
parentNode | 返回节点的父节点。 |
previousSibling | 返回节点之前紧跟的同级节点。 |
textContent | 设置或返回节点及其后代的文本内容。 |
需要注意的是如果要取出节点的值应该用 textContent
而不是 nodeValue
例如
<input /> => 取出value用nodeValue
例如
<text>123</text> => 取出123用textContent
由于xml文档中没 input
这样的标签,所以大部分情况用 textContent
node对象方法
方法 | 描述 |
---|---|
appendChild(newchild) | 向节点的子节点列表的结尾 添加新的子节点。 |
cloneNode(boolean) | 复制节点。True:复制元素及值 |
hasAttributes( ) | 判断当前节点是否拥有属性。 |
hasChildNodes() | 判断当前节点是否拥有子节点。 |
insertBefore(newchild,refchild) | 在指定的子节点前插入新的 子节点。 |
removeChild(node ) | 删除(并返回)当前节点的 指定子节点。 |
replaceChild(new_node,old_node ) | 用新节点替换一个子节点。 |
selectNodes(query) | 用一个 XPath 表达式查询选择节点。 |
selectSingleNode(query) | 查找和 XPath 查询匹配的一个节点。 |
getNodeName() | 获得节点的名称 |
getChildNodes() | 获得子节点集合 |
前面node有一个属性是nodeTypes
NodeType | Named Constant |
---|---|
1 | ELEMENT_NODE |
2 | ATTRIBUTE_NODE |
3 | TEXT_NODE |
4 | CDATA_SECTION_NODE |
5 | ENTITY_REFERENCE_NODE |
6 | ENTITY_NODE |
7 | PROCESSING_INSTRUCTION_NODE |
8 | COMMENT_NODE |
9 | DOCUMENT_NODE |
Element
属性,需要注意的是Element对象继承Node对象,因此Node有的他都有
属性 | 描述 |
---|---|
attributes | 返回元素的属性的 NamedNodeMap |
namespaceURI | 返回元素的命名空间 URI |
ownerDocument | 返回元素所属的根元素 (document 对象) |
tagName | 返回元素的名称 |
方法
方法 | 描述 |
---|---|
getAttribute(name ) | 返回属性的值。 |
getAttributeNode(name) | 以 Attribute 对象返回属性节点。 |
getElementsByTagName(name) | 找到具有指定标签名的子孙元素。 |
removeAttribute(name) | 删除指定的属性。 |
removeAttributeNode(node) | 删除指定的属性节点。 |
setAttribute(name,value) | 添加新属性/重置原属性。 |
setAttributeNode(attrnode) | 添加新的属性节点/重置原属性。 |
上面提到Element有一个属性 attributes
返回值是NamedNodeMap
方法 | 描述 |
---|---|
getNamedItem(nodename ) | 可返回指定的节点(通过名称) |
item(index) | 可返回处于指定索引号的节点 |
习题
- 将这个文档遍历并且打印出来根节点的名称以及各个商品的名称,库存,详细名称。
<?xml version="1.0" encoding="GB2312"?>
<库存>
<牙膏 数量="23盒">中华牌牙膏</牙膏>
<香皂 数量="45块">舒服佳香皂</香皂>
<洗衣粉 数量="19袋">雕牌洗衣粉</洗衣粉>
</库存>
import java.io.*;
import javax.xml.parsers.*;
import org.w3c.dom.*;
public class dom {
public static void main(String[] args) {
try {
// 1 解析xml文档
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse(new File("./dom.xml"));
// 2 获得xml文档根节点
Element element = document.getDocumentElement();
System.out.println(element.getNodeName());
// 3 获得根节点的孩子节点 (注意孩子节点不一定就是元素节点,也可以是文本节点
NodeList nodeList = element.getChildNodes();
int length = nodeList.getLength();
for (int i = 0; i < length; i++) {
// 4. 获得第i个节点
Node node = nodeList.item(i);
// 5. 如果节点类型是元素节点,则强制转换为Element,只有Element对象才有关于attribute的相关方法
if (node.getNodeType() != Node.ELEMENT_NODE) continue;
Element ele = (Element)nodeList.item(i);
System.out.println(ele.getNodeName());
System.out.println(ele.getAttribute("数量"));
System.out.println(ele.getTextContent());
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
- 输出xml文档中的所有属性和文本, 与上一道题类似
<?xml version="1.0" encoding="GB2312" ?>
<学生名单>
<学生 姓名="马洪波" 年龄="20" 性别="男">
三好学生
</学生>
<学生 姓名="周立俊" 年龄="19" 性别="女">
优秀团员
</学生>
</学生名单>
import java.io.*;
import java.security.KeyStore.Entry.Attribute;
import javax.xml.parsers.*;
import org.w3c.dom.*;
public class xmldom2 {
public static void main(String args[]) {
try {
// 1. 解析xml
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse("./dom2.xml");
// 2. 获取xml根节点
Element element = document.getDocumentElement();
System.out.println(element.getNodeName());
// 3. 获取孩子节点
NodeList nodeList = element.getChildNodes();
int len = nodeList.getLength();
for (int i = 0; i < len; i++) {
Node node = nodeList.item(i);
// 4. 排除非元素孩子节点
if (node.getNodeType() != Node.ELEMENT_NODE) continue;
Element ele = (Element) node;
// 5. 获得属性集合 NamedNodeMap
NamedNodeMap namedNodeMap = ele.getAttributes();
int length = namedNodeMap.getLength();
for (int j = 0; j < length; j++) {
// 6. 获取属性 Attr
Attr attr = (Attr) namedNodeMap.item(j);
System.out.println(attr.getName() + ":" + attr.getValue());
}
// 7. 获取元素节点文本
System.out.println(ele.getTextContent().trim());
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
打印出来的结果是
学生名单
姓名:马洪波
年龄:20
性别:男
三好学生
姓名:周立俊
年龄:19
性别:女
优秀团员
动态创建XML文档
- 保存到文件
import java.io.*;
import javax.xml.parsers.*;
import javax.xml.transform.*;
import javax.xml.transform.dom.*;
import javax.xml.transform.stream.*;
import org.w3c.dom.*;
// 1. 创建Document 以及 DOMSource
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.newDocument();
DOMSource domSource = new DOMSource(document);
// 2. 获取转换器
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
// 3. 获取文件输出流
File file = new File('xxx.xml');
FileOutputStream out = new FileOutputStream(file);
StreamResult xmlResult = new StreamResult(out);
// 4.转换
transformer.transform(domSource, xmlResult);
- 添加元素 @todo
Document document = builder.newDocument();
Element element = document.createElement("hello");
document.appendChild(element);
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<hello />
- 修改元素内容
Element element = document.createElement("hello");
element.setTextContent("world");
<hello>world</hello>
- 删除元素
node newNode = node.removeChild(childnode);
- 删除属性
node.removeAttribute(attrname);