dom4J使用笔记
使用dom4j是目前最常用的解析XML的方法,dom4j解析集DOM和SAX技术优点于一身,要使用dom4j 还是先要导入jar:
dom4j-1.6.1.jar (dom4j最主要的jar包,可以独立存在) , jaxen-1.1.6.jar (支持Xpath技术)
需要解析的XML文件:
<?xml version="1.0" encoding="UTF-8"?> <person> <student id="123"> <name>lz</name> <age>21</age> </student> <student> <name>zhanshang</name> <age>20</age> </student> </person>
dom4j解析的步骤:
步骤一:得到Document对象
//1.创建解析器 SAXReader reader=new SAXReader(); //2.解析XML文件,得到Document Document document = reader.read(url);
步骤二 调用Document对象的getRootElement()方法得到根标签,返回的是Element对象
Element root = document.getRootElement();
步骤三 使用ELement的API进行操作,如果没找到想要的方法,可以到其父接口Node中寻找,注意:这里使用的类都是org.dom4j 包下的
Element对象常用的方法:element("标签名")获得该标签的第一个元素 elements()获得所有的子标签 elements("标签名")获得所有的该标签的子元素 getParent()获得父节点 addElement()添加标签 getText()获得文本值 setText("文本值")设置文本值
查询元素
查询操作主要是用element和elements方法
/** * 查询所有name和age的值 * @throws Exception */ @Test public void fun1() throws Exception{ //1.创建解析器 SAXReader reader=new SAXReader(); //2.解析XML文件,得到Document Document document = reader.read("src/person.xml"); //3.得到根标签 Element root = document.getRootElement(); //4.进行具体操作 List<Element> elements = root.elements("student"); for (Element element : elements) { Element name = element.element("name"); String nameText = name.getText(); Element age = element.element("age"); String ageText = age.getText(); System.out.println("name:"+nameText+" age:"+ageText); } }
结果输出:
name:lz age:21
name:zhanshang age:20
查询出某一个元素
查询一:
/** * 查询得到第一个student标签的name * @throws Exception */ @Test public void fun2() throws Exception{ SAXReader reader=new SAXReader(); Document document = reader.read("src/person.xml"); Element root = document.getRootElement(); Element student = root.element("student"); Element name = student.element("name"); System.out.println(name.getText()); }
输出结果为:
lz
查询二:
/** * 查询得到第二个student标签的age * @throws Exception */ @Test public void fun3() throws Exception{ SAXReader reader=new SAXReader(); Document document = reader.read("src/person.xml"); Element root = document.getRootElement(); List<Element> students = root.elements("student"); Element student2 = students.get(1); Element age = student2.element("age"); System.out.println(age.getText()); }
输出结果为:
20
在末尾添加节点
先要确定要添加位置的父节点,然后使用该父节点的addElement("标签名")添加节点,需要添加文本节点的话使用setText("文本值")方法,最后别忘了回写XML
/** * 在末尾添加节点 * @throws Exception */ @Test public void fun4() throws Exception{ //1.创建解析器 SAXReader reader=new SAXReader(); //2.解析XML文件得到Document Document document = reader.read("src/person.xml"); //3.得到根标签 Element root = document.getRootElement(); //在第一个student元素后添加school Element student = root.element("student"); Element school = student.addElement("school"); school.setText("lynu"); //回写XML OutputFormat format=OutputFormat.createPrettyPrint(); //带缩进的格式 XMLWriter writer=new XMLWriter(new FileOutputStream("src/person.xml"), format); writer.write(document); writer.close(); }
回写XML使用的是OutputFormat类和XMLWriter类,这两个类都是org.dom4j.io 包下的,OutputFormat 类还有个createCompactFormat()方法可以压缩XML文件中的空格和换行,使用dom4j不会像jaxp那样破坏XML文件的格式。因为XMLWriter类使用流的技术,所以要记得使用完关闭
结果显示为:
<?xml version="1.0" encoding="UTF-8"?> <person> <student id="123"> <name>lz</name> <age>21</age> <school>lynu</school> </student> <student> <name>zhanshang</name> <age>20</age> </student> </person>
第一个student标签多了个school子标签
在特定位置添加节点
其实在特定位置添加元素就是使用父节点调用elements()方法的其子元素列表,是一个List集合,接下来就是操作List集合,使用List的add(位置,标签) ,当然不要忘了再添加将集合前,将这个元素创建出来:DocumentHelper.createElement(标签名) ,DocumentHelper类也是org.dom4j 包下的
/** * 在特定位置(第二个student的age前面)添加school节点 * @throws Exception */ @Test public void fun5() throws Exception{ SAXReader reader=new SAXReader(); Document document = reader.read("src/person.xml"); Element root = document.getRootElement(); Element student2 = (Element) root.elements().get(1); //得到第二个student List<Element> elements = student2.elements(); //得到student的子标签集合 Element school = DocumentHelper.createElement("school"); //创建school节点 school.setText("lynu"); elements.add(1, school); //在对应为位置添加(操作list集合) //回写XML OutputFormat format=OutputFormat.createPrettyPrint(); XMLWriter writer=new XMLWriter(new FileOutputStream("src/person.xml"), format); writer.write(document); writer.close(); }
结果显示为:
<?xml version="1.0" encoding="UTF-8"?> <person> <student id="123"> <name>lz</name> <age>21</age> <school>lynu</school> </student> <student> <name>zhanshang</name> <school>lynu</school> <age>20</age> </student> </person>
第二个student也都添加了school子节点
修改节点的值
修改节点就是先找到需要修改的节点,然后使用setText("文本值")
/** * 修改节点的值 * @throws Exception */ @Test public void fun6() throws Exception{ SAXReader reader=new SAXReader(); Document document = reader.read("src/person.xml"); Element root = document.getRootElement(); Element student1 = root.element("student"); Element age1 = student1.element("age"); age1.setText("100"); OutputFormat format=OutputFormat.createPrettyPrint(); XMLWriter writer=new XMLWriter(new FileOutputStream("src/person.xml"), format); writer.write(document); writer.close(); }
结果显示为:
<?xml version="1.0" encoding="UTF-8"?> <person> <student id="123"> <name>lz</name> <age>100</age> <school>lynu</school> </student> <student> <name>zhanshang</name> <school>lynu</school> <age>20</age> </student> </person>
第一个student的age修改为100
删除节点
删除节点还是需要先找到其父节点,然后根据父节点调用remove(节点)删除
/** * 删除节点(删除所有school) * @throws Exception */ @Test public void fun7() throws Exception{ SAXReader reader=new SAXReader(); Document document = reader.read("src/person.xml"); Element root = document.getRootElement(); List<Element> elements = root.elements("student"); for (Element element : elements) { //删除节点,需要根据要删除节点的父节点来删除 Element school = element.element("school"); //得到要删除的节点 element.remove(school); } //回写XML OutputFormat format=OutputFormat.createPrettyPrint(); XMLWriter writer=new XMLWriter(new FileOutputStream("src/person.xml"), format); writer.write(document); writer.close(); }
结果显示为:
<?xml version="1.0" encoding="UTF-8"?> <person> <student id="123"> <name>lz</name> <age>100</age> </student> <student> <name>zhanshang</name> <age>20</age> </student> </person>
所有的school标签被删除了
获得属性的值
先得到对应的标签,然后使用attributeValue("属性名")得到属性值
/** * 获得属性值 * @throws Exception */ @Test public void fun8() throws Exception{ SAXReader reader=new SAXReader(); Document document = reader.read("src/person.xml"); Element root = document.getRootElement(); Element student1 = root.element("student"); String id = student1.attributeValue("id"); System.out.println(id); }
结果输出为:
123
第一个student标签上有一个id属性,id属性值为123
XPath
获取某个元素使用dom4j原生的方法虽然很方便,但是使用XPath之后会发现获得一个元素更为方便了,使用dom4j支持XPath就需要 jaxen-1.1.6.jar zhegejar包,先来看看Xpath的语法:
第一种形式:/AAA/DDD/BBB 表示一层一层获得AAA下面的DDD下面的BBB
第二种形式://BBB 表示只要名为BBB的都可以获得
第三种形式:/* 所有元素
第四种形式:BBB[1]表示第一个BBB元素 BBB[last()]表示最后一个BBB元素
第五种形式://BBB[@id] 表示获得所有有id属性的BBB元素
第六种形式://BBB[@id='1'] 表示元素名为BBB,BBB元素有id属性,且属性值为1的元素
dom4j提供了两个方法用于支持XPath : selectNodes("XPath表达式") 获得多个节点, selectSingleNode("XPath表达式") 获得一个节点
获得标签的值
/** * 获得所有name标签的值 * @throws Exception */ @Test public void fun1() throws Exception{ //1.获得document Document document = new SAXReader().read("src/person.xml"); //2.调用Document对象的API,使用XPath表达式 List<Node> list = document.selectNodes("//name"); //遍历输出 for (Node node : list) { System.out.println(node.getText()); } }
结果输出为:
lz
zhanshang
获得某一个标签的值
/** * 获得某一个标签(name)的值 * @throws Exception */ @Test public void fun2() throws Exception{ Document document = new SAXReader().read("src/person.xml"); Node node = document.selectSingleNode("//student[@id='123']/name"); //获得某一个标签 System.out.println(node.getText()); }
结果输出为:
lz