SAX是一种基于事件驱动模式的XML解析API,好处是快,而且节省内存,坏处是程序编写起来相对复杂,而且给人感觉不够OO。最好用的还是DOM,但是占内存太多,极限的时候会引起OutOfMemory异常。
闲话就说道这里,下面开始说程序。sun的JDK1.5中包含我下面程序将用到的所有import的类,所以运行的时候不需要第三方jar包。
//-------------------------------解析消息的主类----------------------------------------
package sax;

import java.io.File;
import java.io.IOException;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;


public class SAXParser extends DefaultHandler ...{

private String filename = null;

// 定义msn消息中的标签名称,为解析作准备

private static final String FirstSessionID = "FirstSessionID";

private static final String LastSessionID = "LastSessionID";

private static final String Message = "Message";

private static final String Date = "Data";

private static final String Time = "Time";

private static final String DateTime = "DateTime";

private static final String SessionID = "SessionID";

private static final String From = "From";

private static final String To = "To";

private static final String Log = "Log";

private static final String FriendlyName = "FriendlyName";

private static final String User = "User";

private static final String Text = "Text";

// 保存一条聊天信息的内容,在消息结束的时候打印
private String data;

private String time;

private String dataTime;

private int sessionID;

private String from;

private String to;

private String text;

// 标记是不是可以打印一个消息了
private boolean textComming = false;


public SAXParser(String filename) ...{
this.filename = filename;
}


public void showMessage() ...{
// boolean validation = false;
// 创建一个解析工厂
SAXParserFactory spf = SAXParserFactory.newInstance();
// 声明一个解析器
javax.xml.parsers.SAXParser saxParser = null;

try ...{
// 创建一个解析器,并借西文档,将this作为事件监听器
saxParser = spf.newSAXParser();
saxParser.parse(new File(filename), this);

} catch (SAXException se) ...{
System.err.println(se.getMessage());
System.exit(1);

} catch (IOException ioe) ...{
System.err.println(ioe);
System.exit(1);

} catch (ParserConfigurationException e) ...{
System.err.println(e);
System.exit(1);
}
}


/**//*
* SAX会将URL中的一些特殊符号做出一些不符合我们想象的分割,可以尝试将这个判断去掉,然后打开一个包含&等特殊符号的msn聊天记录看看会发生什么
*/

private void dealMessage() ...{
//

if (from == null && to == null) ...{
logWithoutLinebreak(this.text);

} else ...{
log("(" + this.dataTime + ")" + from + " 对 " + to + " 说:"
+ this.text);
this.from = null;
this.to = null;
this.text = null;
}
}

// 以下动作会按照顺序发生,其中startElement-characters-endElement是循环的。
@Override

public void startDocument() throws SAXException ...{
super.startDocument();
log("--------开始打印信息---------");
}

@Override
public void startElement(String uri, String localName, String qName,

Attributes attributes) throws SAXException ...{
super.startElement(uri, localName, qName, attributes);

if (Message.equalsIgnoreCase(qName)) ...{
this.data = attributes.getValue(Date);
this.time = attributes.getValue(Time);
this.dataTime = attributes.getValue(DateTime);

} else if (User.equalsIgnoreCase(qName)) ...{

if (this.from == null) ...{
this.from = attributes.getValue("FriendlyName");

} else ...{
this.to = attributes.getValue("FriendlyName");
}

} else if (Text.equalsIgnoreCase(qName)) ...{
textComming = true;

}
}

@Override
public void characters(char[] ch, int start, int length)

throws SAXException ...{
super.characters(ch, start, length);

if (this.textComming) ...{
this.text = new String(ch, start, length);
dealMessage();
}
}

@Override
public void endElement(String uri, String localName, String qName)

throws SAXException ...{
super.endElement(uri, localName, qName);

if (this.textComming) ...{
this.textComming = false;
}
}

@Override

public void endDocument() throws SAXException ...{
super.endDocument();
log("--------打印信息结束---------");
}


private void log(String str) ...{
System.out.print(" " + str);
}


private void logWithoutLinebreak(String str) ...{
System.out.print(str);
}
}


//-------测试---------



/** *//**
*
*/
package sax;

import java.awt.FileDialog;
import java.awt.Frame;


/** *//**
* @author zhuge
*
*/

public class XMLParserTest ...{


public static void main(String[] args) ...{
Frame f = new Frame();
FileDialog dlg = new FileDialog(f, "Open", FileDialog.LOAD);
dlg.setVisible(true);
String filename = dlg.getDirectory() + dlg.getFile();
SAXParser parser = new SAXParser(filename);
parser.showMessage();
dlg = null;
f.dispose();
f = null;

}
}

【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· [AI/GPT/综述] AI Agent的设计模式综述