DOM解析器
DOM的全称是
document object model
。DOM解析器在解析XML文档时,会把文档中的所有元素,按照其出现的层次关系,解析成一个个Node对象(节点)。
DOM结构
把整个xml文档加载到计算机内存中,此时的内存中存放的xml文档是一个树状结构
在DOM中,节点之间关系如下:
位于一个节点之上的节点是该节点的
父节点(parent)
,父节点只有一个
一个节点之下的节点是该节点的
子节点(children)
,子节点有0或多个。
同一层次,具有相同父节点的节点是
兄弟节点(sibling)
,兄弟节点有0或多个。
后代与祖先
一个节点的下一个层次的节点集合是节点后代(descendant)
父、祖父节点及所有位于节点上面的,都是节点的祖先(ancestor)
NODE对象
Node对象,可以表示
元素
、
文本
、
属性
。与Node有关接口的结构如下:
---| Node 描述的是所有的XML元素的共性
------| Document 描述整个XML文档
------| Element 描述XML中的元素(标签)
------| Attr 描述的是所有的XML中的属性元素的共性
------| Text 描述的是Element或Attr中包含的文本内容
------| Comment 描述的是注释中包含的文本内容
DOM4J介绍
Dom4j(
文档对象模for java
)是一个非常优秀的Java XML API,具有性能优异、功能强大和极易使用的特点。现在很多软件采用的Dom4j,例如Hibernate,包括sun公司自己的JAXM也用了Dom4j。
使用Dom4j开发,需下载dom4j相应的jar文件。
Dom4j的官方网站:http://sourceforge.net/projects/dom4j/
DOM4J
常用的方法
Dom4j常用方法:
1.构造方法:
SAXReader():创建一个xml解析器对象
XMLWriter(OutputStream o):创建一个xml输出流对象
XMLWriter(OutputStream o,OutputFormat format):创建带格式的xml输出流对象
2.基本方法:
SAXReader类的方法
基本就是为了获取Document接口的
Node接口的方法
Element getParent();//获取父节点
String getName();//获取节点的名称
short getNodeType();//获取节点的类型
String getNodeTypeName();//获取节点的名称
Document接口的方法
最常用的就是获取根元素的方法
Element接口的方法
Element addAttribute(String name, String value);//通过属性名和值添加属性
Element addComment(String comment);//添加评论
Element addText(String text);//添加元素标签值
void add(Attribute attribute);//直接添加属性
boolean remove(Attribute attribute);//删除属性
String getText();//获取元素的标签值
String elementText(String name);//获取元素的标签值
String getTextTrim();//获取元素的标签值并会忽略文本2端的空白字符
List attributes(); //获取属性集合
int attributeCount();//获取属性个数
Iterator attributeIterator();//获取属性集合迭代器
String attributeValue(String name);//获取某个属性的值
Element element(String name);//获取第一个子元素
List elements();//获取子元素集合
Iterator elementIterator();//获取子元素集合的迭代器
boolean isRootElement();//查询是否是根元素
剩下的就是继承他父接口Node的方法了.
Attribute接口的方法
常用的就是2个
getName:获取属性的名字,其实是继承其父接口Node的方法
getValue:获取属性的值
OutputFormat类
创建输出格式和xml编码
OutputFormat createPrettyPrint();//输出漂亮的格式
OutputFormat createCompactFormat() ;//输出紧凑的格式
setEncoding(String encoding) ;//指定输出格式
下面通过Demo来演示下dom4j读取相关的api使用
项目结构如下:
要读取的文件:
<?xml version="1.0" encoding="UTF-8"?>
<person-list>
<!-- 只是一个注释 -->
<person id="110">
<name>张三</name>
<age>19</age>
<email>123454@qq.com</email>
<address>广州天河</address>
</person>
<person id="220">
<name>李四</name>
<age>20</age>
<email>11111@qq.com</email>
<address>广州番禺</address>
</person>
</person-list>
demo1
package demo1;
import java.io.File;
import java.util.Iterator;
import java.util.List;
import org.dom4j.Attribute;
import org.dom4j.Comment;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.Node;
import org.dom4j.io.SAXReader;
import org.junit.Test;
/**
* SAXReader读取标签元素,节点,属性的基本操作
*
* @author mChenys
*
*/
public class ReaderDemo {
@Test
public void testElement() throws Exception {
// 创建xml解析器
SAXReader saxReader = new SAXReader();
// 加载文件,读取到document中
Document document = saxReader.read("./src/test.xml");
// 通过document对象获取根元素的信息
Element rootEle = document.getRootElement();
// 通过根元素获取下面的所有直接子元素
List<Element> rchilds = rootEle.elements();
// 遍历根元素下所有直接子元素
for (Element e : rchilds) {
// 获取子元素名称
System.out.print(e.getName() + " ");
// 获取子元素的属性
Attribute attr = e.attribute(0);
System.out.println(attr.getName() + "=" + attr.getValue());
// 获取下一级子元素
List<Element> echilds = e.elements();
for (Element e2 : echilds) {
// 获取子元素名称和值
System.out.println("\t" + e2.getName() + "=" + e2.getTextTrim());
}
}
// 根据元素名字获取根元素下某个子元素
Element e = rootEle.element("person");
System.out.println(e.getName());
System.out.println("-------------------------");
}
@Test
public void testNode() throws Exception {
// 创建xml解析器
SAXReader saxReader = new SAXReader();
// 加载文件,获取document
Document document = saxReader.read(new File("./src/test.xml"));
// 获取根元素
Element rootEle = document.getRootElement();
// 获取根元素的所有直接子节点
Iterator<Node> it = rootEle.nodeIterator();
while (it.hasNext()) {
Node node = it.next();
if (node instanceof Comment) {// 注释
System.out.println("注释内容" + node.getText());
} else if (node instanceof Element) {// 标签
System.out.println("标签名字:" + node.getName());
}
}
System.out.println("-------------------------");
}
@Test
public void testAttribute() throws Exception {
// 创建xml解析器
SAXReader saxReader = new SAXReader();
// 加载目标文件
Document doc = saxReader.read(new File("./src/test.xml"));
// 获取根元素
Element root = doc.getRootElement();
// 获取所有直接子元素
List<Element> childs = root.elements();
// 遍历直接子元素
for (Element child : childs) {
// 获取属性集合迭代器
Iterator<Attribute> it = child.attributeIterator();
while (it.hasNext()) {
Attribute attr = it.next();
System.out.println(attr.getName() + "=" + attr.getValue());
}
}
// 获取root的第一个子元素的属性和值
System.out.println(root.element("person").attribute(0).getName());
System.out.println(root.element("person").attribute(0).getValue());
// 获取root的第一个子元素的获取属性的个数
System.out.println(root.element("person").attributeCount());
// 获取root的第一个子元素的获取某个属性的值
System.out.println(root.element("person").attributeValue("id"));
}
}
demo2
package demo2;
import java.io.File;
import java.util.List;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
/**
* 通过递归获取所有节点的标签名字
*
* @author mChenys
*
*/
public class ReaderNameDemo {
public static void main(String[] args) throws Exception {
SAXReader saxReader = new SAXReader();
Document doc = saxReader.read(new File("./src/test.xml"));
Element root = doc.getRootElement();
readXml(root);
}
private static void readXml(Element e) {
System.out.println(e.getName());
List<Element> next = e.elements();
for(Element e2 : next) {
readXml(e2);
}
}
}
demo3
package demo3;
import java.io.File;
import java.util.Iterator;
import java.util.List;
import org.dom4j.Attribute;
import org.dom4j.Comment;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.Node;
import org.dom4j.Text;
import org.dom4j.io.SAXReader;
/**
* 把xml文件的所有标签名名字、属性、标签体、注释、空白处 等...的内容全部打印出来,格式要求与xml文件的内容。
* @author mChenys
*
*/
public class ReaderAllDemo {
public static void main(String[] args) throws Exception {
SAXReader saxReader = new SAXReader();
Document doc = saxReader.read(new File("./src/test.xml"));
Element root =doc.getRootElement();
StringBuilder sb = new StringBuilder();
readXml(root,sb);
System.out.println(sb);
}
public static void readXml(Element element,StringBuilder sb){
sb.append("<"+element.getName());
//获取到属性迭代器添加所有的属性
Iterator<Attribute> attriIt = element.attributeIterator();
while(attriIt.hasNext()){
Attribute attribute = attriIt.next();
sb.append(" "+attribute.getName()+"=\""+attribute.getValue()+"\"");
}
//添加结束开始标签的符号
sb.append(">");
//获取所有的子节点
Iterator<Node> it = element.nodeIterator();
while(it.hasNext()){
Node node = it.next();
if(node instanceof Text){
//文本
sb.append(node.getText());
}else if(node instanceof Comment){
//注释
sb.append("<!--"+node.getText()+"-->");
}else if(node instanceof Element){
//迭代读取下一个元素
readXml((Element) node, sb);
}
}
//添加结束标签
sb.append("</"+element.getName()+">");
}
}