1.Dom
原理 就是把整个文档加载到内存 生成一个树状结构 dom tree
优点 可以修改文档
缺点 比较占用内存
@Test
public void domParseTest() throws Exception{
//①获取DocumentBuilderFactory
DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
//②获取DocumentBuilder
DocumentBuilder documentBuilder = builderFactory.newDocumentBuilder();
//③获取Document
Document document = documentBuilder.parse("book.xml");
//通过节点的名字 找到所有的同名的节点
NodeList nodeList = document.getElementsByTagName("对应的名字");
Node item = nodeList.item(0);
//通过节点获取节点的内容
String textContent = item.getTextContent();
System.out.println("textConent==="+textContent);
}
通过dom修改文档
public void domModifyTest() throws Exception{
//获取DocumentBuilderFactory
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
//获取DocumentBuilder
DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
//通过DocumentBuilder 解析文件 拿到document对象
Document document = documentBuilder.parse("book.xml");
//找到售价节点
NodeList nodeList = document.getElementsByTagName("price");
Node node = nodeList.item(0);
//设置文本内容
node.setTextContent("20.00");
//transformer
TransformerFactory transformerFactory = TransformerFactory.newInstance();
//通过工厂获得transformer
Transformer transformer = transformerFactory.newTransformer();
//通过transformer 把内存中的修改保存到文件中
//指定数据源 把刚解析出来的document对象作为数据源
Source arg0 = new DOMSource(document);
//指定 修改之后保存结果的对象 创建一个StreamResult(流结果) 保存到本地文件 book.xml
Result arg1 = new StreamResult("book.xml");
transformer.transform(arg0, arg1);
}
2.sax
一个元素一个元素的解析优点 占用内存小 随时可以停下
步骤思路:
①SaxParserFactory
② 获取SAXParser
③ 获取XMLReader
④ 给XMLReader设置处理器 setContentHandler
⑤ 开始解析
public class SaxParserTest {
@Test
public void saxParse() throws Exception {
// ①获取SaxParserFactory
SAXParserFactory parserFactory = SAXParserFactory.newInstance();
// ②获取SaxParser
SAXParser parser = parserFactory.newSAXParser();
// ③通过SaxParser获取xmlReader
XMLReader xmlReader = parser.getXMLReader();
// 给xmlreader添加内容处理程序
// xmlReader.setContentHandler(new MyHandler());
xmlReader.setContentHandler(new DefaultHandler() {
int count = 0;
boolean isAuthor = false;
@Override
public void characters(char[] ch, int start, int length)
throws SAXException {
if (count == 2 && isAuthor) {
System.out.println("文本内容==="
+ new String(ch, start, length));
// count = 0;
}
}
@Override
public void startDocument() throws SAXException {
}
@Override
public void startElement(String uri, String localName,
String qName, Attributes atts) throws SAXException {
// System.out.println("解析到开始标签=========<"+qName+">");
if ("author"".equals(qName)) {
count++;
isAuthor = true;
}
}
@Override
public void endElement(String uri, String localName, String qName)
throws SAXException {
if ("author".equals(qName)) {
isAuthor = false;
}
}
@Override
public void endDocument() throws SAXException {
}
});
xmlReader.parse("book.xml");
}
3.pull解析
优点 占用内存小 随时可以停下
public class XMLPullParserTest {
@Test
public void pullTest() throws Exception {
//声明一个arraylist用来存放解析的结果
ArrayList<Book> books = null;
int count = 0;
//创建一本书 用来保存 每一个<book></book>节点中的内容
Book book = null;
XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
XmlPullParser xpp = factory.newPullParser();
// 给解析器设置输入源 第一个参数 输入流 第二个参数 编码集
xpp.setInput(new FileInputStream("book.xml"), "utf-8");
//通过getEventType 获取当前解析到的节点类型
int eventType = xpp.getEventType();
while (eventType != XmlPullParser.END_DOCUMENT) {
switch (eventType) {
//处理开始标签
case XmlPullParser.START_TAG:
if("bookshelf".equals(xpp.getName())){
//解析到<书架> 准备集合
books = new ArrayList<Book>();
}else if("book".equals(xpp.getName())){
//new book() 准备一本书
book = new Book();
}else if("booktitle".equals(xpp.getName())){
// 给book.title赋值
book.title = xpp.nextText();
}else if("author".equals(xpp.getName())){
// 给book.author赋值
book.author = xpp.nextText();
}else if("price".equals(xpp.getName())){
// 给book.price赋值
book.price = xpp.nextText();
}
break;
//处理结束标签
case XmlPullParser.END_TAG:
if("书".equals(xpp.getName())){
//把book放到集合中
books.add(book);
//给book置空
book = null;
count++;
}
break;
}
// // 不断的解析
// if(count == 1){
// break;
// }
//调用xpp.next() 解析下一个元素 用eventType 接收返回值
eventType = xpp.next();
}
//遍历集合
for(Book book1:books){
System.out.println(book1);
}
}
}