dom解析和sax解析区别:
dom方式解析:
- 根据xml的层级结构在内存中分配一个数型结构,把xml的标签、属性和文本都封装成对象
- 优点:很方便实现增删改操作
- 缺点:如果文件过大会造成内存溢出
sax方式解析:
- 采用事件驱动,边读边解析。从上到下,一行一行的解析,解析到某个对象,返回对象名称。
- 优点:如果文件过大,不会造成内存溢出,方便实现查询操作。
- 缺点:不能实现增删改操作。
jaxp的api的查看
jaxp是javase的一部分,jaxp解析器在jdk的javax.xml.parsers包里面
四个类:分别正对dom和sax解析使用
- dom:
- DocumentBuilder:解析器类
这个类是抽象类,不能new.
此类的实例可以从DocumentBuilderFactory.newDocumentBuilder()
方法中获取.
parse("xml路径")
,返回的是整个Document文档对象.
getElementsByTagName(String tagname)
,返回NodeList集合.
createElement(String tagName)
,创建标签.
createTextNode(String data)
,创建文本.
appendChildNode(Node newChild)
,把文本添加到标签下面.
removeChild(Node oldChild)
,删除节点.
getParentNode()
,获取父节点.
getTextContent()
,得到元素值.
- DocumentBuilderFactory:解析器工厂
这个类也是抽象类,不能new
通过newInstance()
方法获取DocumentBuilderFactory的实例。
- sax:
SAXParser : 解析器类
通过SAXParserFactory.newSAXParser()方法获得.
parse(File f, DefaultHandler dh)
方法,DefaultHandler为事件处理器.
SAXParserFactory:解析器工厂
通过SAXParserFactory.newInstance()方法创建.
sax执行过程
- 当解析到开始标签时,自动执行startElement()方法
- 当解析到文本时,自动执行character()方法
- 当解析到结束标签时,自动执行endElement()方法
dom方式查询节点
public class TestJaxp{
public static void main(String[] args) throws Exception{
//创建解析工厂
DocumentBuilderFactory builderFactory = DocumentBuilderFacytory.newInstance();
//创建解析器
DocumentBuilder builder = builderFactory.newDocumentBuilder();
//解析xml返回Document对象
Document document = builder.parse("src/persion.xml");
//得到name元素
NodeList list = document.getElementsByTagName("name");
//遍历集合
for(int i=0; i<list.getLength(); i++){
Node name1 = list.item(i);//得到每一个name元素
//得到name元素里面的值
String s = name1.getTextContent();
System.out.println(s);
}
}
}
sax方式查询节点
public class TestJaxp{
public static void main(String[] args) throws Exception{
//创建解析工厂
SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
//创建解析器
SAXParser saxParser = saxParserFactory.newSAXParser();
//解析xml返回Document对象
saxParser.parse("src/persion.xml", new MyDefault1());
}
}
class MyDefault1 exitends DefaultHanlder{
@override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException{
Systeom.out.println("start: "+qName);
}
@override
public void characters(char[] ch, int start, int length) throws SAXException{
System.out.println("text: "+ new String(ch,start,length));
}
@override
public void endElement(String uri, String localName, String qName, ) throws SAXException {
System.out.println("end: "+qName);
}
}
dom4j
getRootElement()
: 获取根节点,返回Element
getParent()
: 获取父节点
addElement()
: 添加标签
dom4j方式查询节点
public class TestDom4j{
public static void main(String[] args){
selectName();
}
//查询xml中所有name元素的值
public static void selectName() throws Exception{
//创建解析器
SAXReader saxReader = new SAXReader();
//得到document
Document document = saxReader.read("src/p1.xml");
//得到根节点
Element root = document.getRootElement();
//得到p1
List<Element> list = root.elements("p1");
//遍历list
for(Element element : list){
//得到p1下面的name元素
Element name1 = element.element("name");
//得到name里面的值
String s = name1.getText();
System.out.println(s);
}
}
}
回写xml
//有缩进效果
OutputFormat format = OutputFormat.createPrettyPrint();
//OutputFormat format = OutputFormat.createCompactFormat();
XMLWriter xmlWriter = new XMLWriter(new FileOutputStream("src/p1.xml"),format);
xmlWriter.write(document);
xmlWriter.close();
dom4j支持xpath操作(默认不支持,需要导入jar包)
可以直接获取某个元素
- /AAA/BBB/CCC:表示AAA下面的BBB下面的CCC
- //BBB:表示选择所有BBB元素
- /* : 表示选择所有元素
- BBB[1]: 表示第一个BBB元素
BBB[last()] : 表示最后一个BBB元素 - //BBB[@id]: 表示只要BBB上面有id属性,都得到
- //BBB[@id='b1']: 表示元素名称是BBB,并且id属性值为b1的元素
两个方法支持xpath:
- selectNodes("xpath表达式");--获取多个节点
- selectStringNode(“xpath表达式”);--获取一个节点
使用xpath查询
public static void test() throws Exception {
//创建解析器
SAXReader saxReader = new SAXReader();
//得到document
Document document = saxReader.read("src/p1.xml");
//使用selectNodes("//name")方法得到所有name元素
List<Node> list = document.selectNodes("//name")
for(Node node : list) {
//node是每一个name元素
String s = node.getText();
System.out.println(s);
}
}
网友评论