JavaWeb--XML的解析(2)
一、DOM4J是什么
- DOM4J是针对Java开发人员专门提供的XML文档解析规范,它不同与DOM,但与DOM相似。DOM4J针对Java开发人员而设计,所以对于Java开发人员来说,使用DOM4J要比使用DOM更加方便。
- DOM4J同时对DOM和SAX提供了支持。
二、DOM4J依赖jar包
因为DOM4J并非JavaSE中的API,因此使用Dom4j开发,需下载dom4j相应的jar文件。
三、DOM4J获得Document对象的方式
1.读取XML文件,获得document对象
SAXReader reader = new SAXReader();
Document document = reader.read(new File("input.xml"));
2.解析XML形式的文本,得到document对象.
String text = "<members></members>";
Document document = DocumentHelper.parseText(text);
3.主动创建document对象.
Document document = DocumentHelper.createDocument();
四、DOM4J解析XML文件实例
现有如下xml文件:
<?xml version="1.0" encoding="UTF-8"?>
<person>
<p1 id="aaa">
<name>zhangsan</name>
<age>300</age>
<gender>m</gender>
</p1>
<p1>
<name>lisi</name>
<age>30</age>
<gender>男</gender>
</p1>
</person>
操作一:获取所有name标签中的文本值
public static void selectAll() throws Exception{
//获取解析器
SAXReader reader = new SAXReader();
//获取document对象
Document doc = reader.read("src/zuobiao/testDom4j/person.xml");
//获取根标签
Element root = doc.getRootElement();
//获取所有的p1标签
List<Element> p1s = root.elements("p1");
//获取所有p1下面的name标签
Element name = null;
for(Element p1:p1s){
name = p1.element("name");
//获取name标签的文本值
System.out.println(name.getText());
}
}
所用方法:
SAXReader():通过调用该构造方法,来创建一个解析器对象
read():解析器调用该方法来获取解析后的文档
getRootElement():获取该xml文件的根标签
elements("标签名"):父标签调用该方法,获取所有指定标签名的子标签,返回一个List对象
element(("标签名"):父标签调用该方法,获取指定标签名的子标签,返回一个Element对象
getText():标签调用此方法,获取该标签的文本值
操作二:在第一个p1的最后添加一个gender标签
public static void addElementTest() throws Exception{
//获取解析器对象
SAXReader reader = new SAXReader();
//获取解析后的document对象
Document doc = reader.read("src/zuobiao/testDom4j/person.xml");
//获取root
Element root = doc.getRootElement();
//获取第一个p1
Element p1 = root.element("p1");
//添加gender标签
Element gender = p1.addElement("gender"); //在末尾加的时候,不用手动创建标签
//给gender标签的文本值设置为男
gender.setText("男");
//回写操作
OutputFormat format = OutputFormat.createPrettyPrint();
XMLWriter writer = new XMLWriter(new FileOutputStream("src/zuobiao/testDom4j/person.xml"), format);
//格式为:XMLWriter(OutputStream out, OutputFormat format)
writer.write(doc);
writer.close(); //涉及到流的操作,一定要记得关闭
}
所用方法:
addElement("标签名"):父标签调用该方法,创建指定名称的标签,并将此标签添加进来
setText("文本内容"):标签调用此方法,设置自己的文本值
OutputFormat format = OutputFormat.createPrettyPrint():创建输出到XML后的格式
new XMLWriter(参数1, 参数2):创建回写对象
- 参数1:输出流
- 参数2:输出格式对象
write(文档对象):回写对象调用该方法,将修改后的文档对象写回到XML文件
writer.close():关闭输出流
操作三:第二个p1标签下的age标签前面添加school标签
public static void addBefore() throws Exception{
//创建解析器对象
SAXReader saxReader = new SAXReader();
//获取解析后的document对象
Document doc = saxReader.read("src/zuobiao/testDom4j/person.xml");
//获取root对象
Element root = doc.getRootElement();
//获取第二个p1标签
List<Element> p1s = root.elements("p1");
Element p1 = p1s.get(1);
//获取p1标签下面的所有标签,返回为list
List<Element> eles = p1.elements();
//创建school标签
Element school = DocumentHelper.createElement("school");
//给school标签设置文本值
school.setText("HUFE");
//list调用add(int index, E element)方法插入标签
eles.add(1, school);
//写回
OutputFormat format = OutputFormat.createPrettyPrint();
XMLWriter xmlWriter = new XMLWriter(new FileOutputStream("src/zuobiao/testDom4j/person.xml"), format);
xmlWriter.write(doc);
xmlWriter.close();
}
所用方法:
DocumentHelper.createElement("标签名"):根据给定的标签名创建标签,并返回该标签对象
eles.add(1, school):此处是list调用add(int index, E element)方法在指定位置插入指定标签
注意:
- 如果是在父标签末尾添加标签,则直接使用addElement("标签名")方法即可;
- 但是如果实在父标签中的指定位置添加标签,则需要使用DocumentHelper.createElement("标签名")方法。因为需要 获取Element对象
操作四:修改第一个p1下面的age标签的文本值
private static void modifyAge() {
//创建解析器对象
SAXReader saxReader = new SAXReader();
//获取解析后的document对象
Document doc = saxReader.read("src/zuobiao/testDom4j/person.xml");
//获取根节点
Element root = doc.getRootElement();
//获取第一个p1
Element p1 = root.element("p1");
//获取age
Element age = p1.element("age");
//修改age标签的文本值
age.setText("300");
//回写
OutputFormat format = OutputFormat.createPrettyPrint();
XMLWriter xmlWriter = new XMLWriter(new FileOutputStream("src/zuobiao/testDom4j/person.xml"), format);
xmlWriter.write(doc);
xmlWriter.close();
}
使用方法:
setText("文本内容"):标签调用此方法,设置自己的文本值
操作五:删除第一个p1下面的school标签
public static void delSch(){
//创建解析器对象
SAXReader saxReader = new SAXReader();
//获取解析后的document对象
Document doc = saxReader.read("src/zuobiao/testDom4j/person.xml");
//得到root
Element root = doc.getRootElement();
//获取p1
Element p1 = root.element("p1");
//得到school
Element school = p1.element("school");
//删除
p1.remove(school);
//写回
OutputFormat format = OutputFormat.createPrettyPrint();
XMLWriter xmlWriter = new XMLWriter(new FileOutputStream("src/zuobiao/testDom4j/person.xml"), format);
xmlWriter.write(doc);
xmlWriter.close();
}
使用方法:
remove(标签对象):父标签调用此方法,删除指定子标签
操作六:获取第一个p1的id属性
private static void getValue() {
//创建解析器对象
SAXReader saxReader = new SAXReader();
//获取解析后的document对象
Document doc = saxReader.read("src/zuobiao/testDom4j/person.xml");
//得到root
Element root = doc.getRootElement();
//获取p1
Element p1 = root.element("p1");
//获取属性值
String str = p1.attributeValue("id");
System.out.println(str);
}
所用方法:
attributeValue("属性名"):标签调用此方法获取指定属性名的属性值
五、DOM4J对XPath的支持
(一)什么是XPath
要从 XML 文档中提取信息,最快捷简单的办法就是在程序中嵌入 XPath 表达式。XPath是一种为查询 XML 文档而设计的查询语言。
(二)XPath选择节点时常用的路径表达式
第一种形式
/AAA/DDD/BBB: 表示一层一层的,AAA下面的DDD下面的BBB
第二种形式
//BBB: 表示第二层中只要名称是BBB,都得到
第三种形式
/*: 所有元素
第四种形式
BBB[1]: 表示第一个BBB元素
BBB[last()]:表示最后一个BBB元素
第五种形式
//BBB[@id]: 表示第二层中只要BBB元素上面有id属性,都得到
第六种形式
//BBB[@id='b1'] 表示第二层中名称是BBB,上面有id属性,并且id的属性值是b1的标签
(三)在DOM4J里面提供了两个方法,用来支持XPath
selectNodes("xpath表达式"):获取多个节点
selectSingleNode("xpath表达式"):获取一个节点
(四)DOM4J和XPath结合的实例(需要外部jar包)
操作一:获取所有的name标签
public static void selectAllName() {
//创建解析器对象
SAXReader saxReader = new SAXReader();
//获取解析后的document对象
Document doc = saxReader.read("src/zuobiao/testDom4j/person.xml");
//document对象使用selectNodes()
List<Node> names = doc.selectNodes("//name"); //因为XPath也可以获取属性,所以返回值统一为Node
//获取每个name标签的文本值
for(Node name:names){
System.out.println(name.getText());
}
}
操作二:获取第一个p1标签下面的name标签的文本值
public static void selectSingleName(){
//创建解析器对象
SAXReader saxReader = new SAXReader();
//获取解析后的document对象
Document doc = saxReader.read("src/zuobiao/testDom4j/person.xml");
//获取第一个p1标签下面的name标签
Node name = doc.selectSingleNode("//p1[@id='aaa']/name");
//获取文本值
System.out.println(name.getText());
}
Java新手,若有错误,欢迎指正!