Day 12
sax解析原理
sax方式:事件驱动,边读边解析
当解析到开始标签的时候,自动执行startElement方法
当解析到文本时候,自动执行characters方法
当解析到标签的时候,自动执行endElement方法
使用jaxp的sax方法来解析xml
只能查询,不可以增删改:查询所有内容
publicclass TestSax {
publicstaticvoid main(String[] args) throws Exception {
//创建解析器工厂
SAXParserFactory saxp = SAXParserFactory.newInstance();
//创建解析器
SAXParser sax = saxp.newSAXParser();
//执行parse方法
sax.parse("src/p2.xml", new MyDefault());
}
}
class MyDefault extends DefaultHandler{
publicvoid startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
// TODO Auto-generated method stub
super.startElement(uri, localName, qName, attributes);
System.out.println("start:"+qName);
}
publicvoid characters(char[] ch, intstart, intlength) throws SAXException {
// TODO Auto-generated method stub
super.characters(ch, start, length);
System.out.println("text:"+new String(ch,start,length));
}
publicvoid endElement(String uri, String localName, String qName) throws SAXException {
// TODO Auto-generated method stub
super.endElement(uri, localName, qName);
System.out.println("end:"+qName);
}
}
使用dom4j解析xml
dom4j是一个组织,针对xml解析,提供解析器 dom4j
dom4j不是Javase的一部分,想要使用需要
1 导入dom4j提供的jar包
-创建一个文件夹lib
-复制jar包到lib下面
-右键点击jar包,buildpath-----》add to buildpath
-看到jar包,变成奶瓶的样子,表示导入成功
2 得到 document
-SAXReader reader = new SAXReader();
-Document document = reader.read(url);
3 document 的父节点是Node
-如果在document里面找不到想要的方法,到Node里面找
-getRootElement();获取根节点,返回的是Element
-Element和Node里面的方法
getPatent()获取父节点
使用dom4j查询xml
目的:查询name里面的值
publicstatic void selectName() {
//创建解析器
SAXReader saxreader = new StringReader();
//得到document
Document document = saxreader.read("src/p1.xml");
//得到根节点
Element root = document.getRootElement();
//得到p1
List<Element> list = root.elements("p1");
//遍历list
for(Element element : list) {
//得到每一个name元素
Element name1 = element.element("name");
//得到name里面的值
String s = name1.getText();
System.out.println(s);
}
标签对象.elements(“标签名”):得到这个标签的所有对象,返回值是一个list
标签对象.element(“标签名”):得到这个标签下面的第一个对象
标签对象.element():得到标签对象下面的所有标签,返回值是一个list
使用dom4j实现添加操作
在第一个p1标签末尾添加一个元素
publicstaticvoid add() {
//创建解析器
SAXReader reader = new SAXReader();
//得到document
Document document = reader.read("src/p1.xml");
//得到根节点
Element root = document.getRootElement();
//获取到第一个p1节点
Element p11 = root.element("p1");
//在p1下面添加元素
Element sex1 = p11.addElement("sex");
//在添加完成之后的元素下面文本
sex1.setText("nv");
//回写xml
OutputFormat format = OutputFormat.createPrettyPrint();//表示添加的元素有缩进的效果
XmlWriter xmlWriter = new XMLWriter(new FileOutputStream("src/p1.xml"),format);
xmlWriter.write(document);
}
实现在p1 标签下的第二个元素下面添加一个元素
publicstaticvoid addbeage() {
//创建解析器
SAXReader reader = new SAXReader();
//得到document
Document document = reader.read("src/p1.xml");
//得到根节点
Element root = document.getRootElement();
//获取到第一个p1节点
Element p11 = root.element("p1");
//得到p1下面所有的节点
List<Element> list = p11.getElements();
//创建标签
Element school = DocumentHelper.createElement("school");
//添加文本
school.setText("henan");
//添加元素
list.add(1,school);
//回写xml
OutputFormat format = OutputFormat.createPrettyPrint();
XMLWriter xmlWriter = new XMLWriter(new FileOutputStream("src/p1.xml"),format);
xmlWriter.write(document);
xmlWriter.close();}
Dom4j里面封装方法的操作
封装回写的操作:
public static void xmlWriter(String path , Document document){
try{
OutputFormat format =OutputFormat.createPrettyPrint();
XMLWriter xmlWriter = newXMLWriter(new FileOutputStream(path),format);
xmlWriter.writer(document);
xmlWriter.close();
}catch(Exception e){
e.printStackTrace();}}
调用:xmlWriter(“src/p1.xml”,document);
地址也可以封装成常量
Public static final String PATH= “src/p1.xml”;
这样的话如果想要修改路径直接在辅助类里面就可以修改,增加了代码的可维护性,增加开发速度
使用dom4j实现修改的操作
修改第一个P1下面的值:
首先封装document:
publicclass Dom4jUtil {
publicstaticfinal String PATH = "src/p1.xml";
publicstatic Document getDocument(String PATH) {
//创建解析器
SAXReader reader = new SAXReader();
//得到document
Document document = reader.read(PATH);
}
封装回写的方法:
publicstaticvoid xmlWriter(String path, Document document) {
try {
OutputFormat format = OutputFormat.createPrettyPrint();
XMLWriter xmlWriter = new XMLWriter(new FileOutputStream(path), format);
xmlWriter.writer(document);
xmlWriter.close();
} catch (Exception e) {
e.printStackTrace();
}
}
具体步骤:
调用封装document的方法:
1 publicstaticvoid updatavalue() {
//调用方法
Document document = Dom4jUtil.getDocument(PATH);
//得到父节点
Element root = document.getRootElement();
//得到P1节点
ELementp1 = root.element("p1");
//得到p1下面的age
Element age = p1.element("age");
//修改age的值
age.setText("300");
//调用回写的方法
Dom4jUtil.xmlWriter(PATH, document);
}
使用dom4j删除节点:
注意:必须通过父节点调用才可以删除
Element p1 = root.element();
Elemenr sch = p1.element(“school”);
P1.remove(sch);
使用dom4j得到标签的属性值
使用方法 String value = p1.attributeValue(“属性名称”);
得到p1标签这里面属性的值
使用dom4j支持xpath的操作
可以直接获取到某一个元素:
第一种形式:/AAA/BBB/DDD表示一层一层的:AAA下面的BBB下面的DDD
第二种形式://BBB:表示只要名称是BBB都可以得到
第三种形式://AAA/*表示AAA下面的所有的元素
第四种形式://BBB[1],BBB[list()]表示分别表示一个标签下第一个和最后一个BBB元素
第五种形式://BBB[@id]:表示只要BBB元素上面有id属相就可以得到
第六种形式://BBB[@id=’b1’]:表示元素名称是BBB 并且在BBB上有属性,属性值值b1
使用dom4j支持xpath具体的操作
步骤:默认情况下dom4j 不支持xpath ,想要使用首先导入jar包 jaxen-1.1-beta-6.jar
在dom4j中提供了两个方法用来支持xpath
****selectNodes(“xpath表达式”); 获取多个节点,返回值是Node形式的Element
****selectSingleNode(“xpath表达式”);获取一个节点 返回值是Element
使用xpath来获取所有标签名是name的值
//获取document
Document document = Dom4jUtil.getDocument(Dom4jUtil .PATH);
//调用方法
List<Node> list = document.selectNodes(“//name”);
//遍历
for(Node node : list){
String s = node.getText();
System.out.println(s);
}
使用xpath来实现得到p1下面的name的值
P1标签中有属性,属相是id属性的值是aaa:
Node node = Document.selectSingNode(“//p1[@id=’aaa’]”/name);