xml解析中的sax解析:
1,工作方式:
逐步扫描xml文档,当遇到标签时触发解析处理器,通过事件处理的方式来解析xml。
2,优点:
不需要文件整个内容加载到内存,只需要逐步扫描一部分内容,通过方法处理数据。
缺点:
每次解析只能处理一次数据,要想重复处理只能再次加载。还有只能进行查询操作,不能进行增删改查操作。
3,代码的具体实现:
解析的xml文件:
<?xml version="1.0" encoding="gbk"?>
<书架>
<书>
<书名>西游记</书名>
<作者>吴承恩</作者>
<价格>188</价格>
</书>
<书>
<书名>三国</书名>
<作者>罗贯中</作者>
<价格>188</价格>
</书>
<书>
<书名>水浒传</书名>
<作者>施耐庵</作者>
<价格>188</价格>
</书>
<书>
<书名>红楼梦</书名>
<作者>曹雪芹</作者>
<价格>188</价格>
</书>
</书架>
3.1通过java对xml文件解析代码:
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.Attributes;
import org.xml.sax.ContentHandler;
import org.xml.sax.Locator;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
public class SaxJiexi {
public static void main(String[] args) throws Exception{
// TODO Auto-generated method stub
//1.获取解析器工厂
SAXParserFactory factor=SAXParserFactory.newInstance();
//2.获取解析器
SAXParser parser=factor.newSAXParser();
//3.获取读取器
XMLReader reader=parser.getXMLReader();
//4.注册事件处理器,对读取到的标签进行处理。
reader.setContentHandler(new MyContentHandler());
//5.解析xml文件
reader.parse("book.xml");
}
}
class MyContentHandler implements ContentHandler{
@Override
public void setDocumentLocator(Locator locator) {
// TODO Auto-generated method stub
}
@Override
public void startDocument() throws SAXException {
// TODO Auto-generated method stub
System.out.println("文档解析开始了");
}
@Override
public void endDocument() throws SAXException {
// TODO Auto-generated method stub
System.out.println("文档解析结束了");
}
@Override
public void startPrefixMapping(String prefix, String uri)
throws SAXException {
// TODO Auto-generated method stub
}
@Override
public void endPrefixMapping(String prefix) throws SAXException {
// TODO Auto-generated method stub
}
@Override
public void startElement(String uri, String localName, String qName,
Attributes atts) throws SAXException {
// TODO Auto-generated method stub
System.out.println("发现了开始标签"+qName);
}
@Override
public void endElement(String uri, String localName, String qName)
throws SAXException {
// TODO Auto-generated method stub
System.out.println("发现了结束标签"+qName);
}
@Override
//标签体的内容
public void characters(char[] ch, int start, int length)
throws SAXException {
// TODO Auto-generated method stub
System.out.println(new String(ch,start,length));
}
@Override
public void ignorableWhitespace(char[] ch, int start, int length)
throws SAXException {
// TODO Auto-generated method stub
}
@Override
public void processingInstruction(String target, String data)
throws SAXException {
// TODO Auto-generated method stub
}
@Override
public void skippedEntity(String name) throws SAXException {
// TODO Auto-generated method stub
}
}
3.2上面的代码,通过创建myCtenthendler实现Ctenthendler接口来对解析到的数据进行处理,但是要想只对xml文件中某一个标签进行查询,就显得代码过于缀余。有一个类DefaultHandler实现了Ctenthendler中的所有的方法,不想使用的方法父类已经空实现了,想要实现的方法,可以覆盖父类的方法,这种设计模式,叫做适配器模式。
class MyContentHandler2 extends DefaultHandler{
private String name=null;
@Override
public void startDocument() throws SAXException {
// TODO Auto-generated method stub
}
@Override
public void endDocument() throws SAXException {
// TODO Auto-generated method stub
}
@Override
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
// TODO Auto-generated method stub
this.name=qName;
}
@Override
public void endElement(String uri, String localName, String qName)
throws SAXException {
// TODO Auto-generated method stub
this.name=null;
}
@Override
public void characters(char[] ch, int start, int length)
throws SAXException {
// TODO Auto-generated method stub
if("书名".equals(name)){
System.out.println(new String(ch,start,length));
}
}
}
上面代码,筛选书名内的标签体内容。解析器调用characters方法来报告字符数据的每个存储块。xml中的回车换行也属于标签体内容,所以这里再在endElement中将name设置为null;
网友评论