我正在尝试使用SAX解析XML。以下是代码段:
public class ReadXML {
public static void main(String argv[]) {
try {
SAXParserFactory factory = SAXParserFactory.newInstance();
SAXParser saxParser = factory.newSAXParser();
DefaultHandler handler = new DefaultHandler() {
boolean bfname = false;
boolean blname = false;
boolean bnname = false;
boolean bsalary = false;
public void startElement(String uri, String localName,String qName,
Attributes attributes) throws SAXException {
System.out.println("Parameters :" + uri +":"+ localName +":"+ qName +":"+ attributes);
System.out.println("Start Element :" + qName);
if (qName.equalsIgnoreCase("FIRSTNAME")) {
bfname = true;
}
if (qName.equalsIgnoreCase("LASTNAME")) {
blname = true;
}
if (qName.equalsIgnoreCase("NICKNAME")) {
bnname = true;
}
if (qName.equalsIgnoreCase("SALARY")) {
bsalary = true;
}
}
public void endElement(String uri, String localName,
String qName) throws SAXException {
System.out.println("End Element :" + qName);
}
public void characters(char[] ch, int start, int length) throws SAXException {
System.out.println("Im here:"+Arrays.toString(ch));
if (bfname) {
System.out.println("First Name : " + new String(ch, start, length));
bfname = false;
}
if (blname) {
System.out.println("Last Name : " + new String(ch, start, length));
blname = false;
}
if (bnname) {
System.out.println("Nick Name : " + new String(ch, start, length));
bnname = false;
}
if (bsalary) {
System.out.println("Salary : " + new String(ch, start, length));
bsalary = false;
}
}
};
saxParser.parse("C:\\Lenny\\Work\\XML\\SaxParsing_01.xml", handler); --(1)
} catch (Exception e) {
e.printStackTrace();
}
}
}
我的第一个问题是,当代码到达saxParser.parse("C:\\Ashish\\Work\\XML\\SaxParsing_01.xml", handler);
时,下面有两个方法被调用..!
public void parse(File f, HandlerBase hb)
throws SAXException, IOException {
if (f == null) {
throw new IllegalArgumentException("File cannot be null");
}
String escapedURI = FilePathToURI.filepath2URI(f.getAbsolutePath());
if (DEBUG) {
System.out.println("Escaped URI = " + escapedURI);
}
InputSource input = new InputSource(escapedURI);
this.parse(input, hb);
}
public void parse(InputSource is, DefaultHandler dh)
throws SAXException, IOException {
if (is == null) {
throw new IllegalArgumentException("InputSource cannot be null");
}
XMLReader reader = this.getXMLReader();
if (dh != null) {
reader.setContentHandler(dh);
reader.setEntityResolver(dh);
reader.setErrorHandler(dh);
reader.setDTDHandler(dh);
}
reader.parse(is);
}
我很想知道,在调用reader.parse(is)
时会发生什么?我唯一假设的是,reader
正在读取XML并放入上面代码中创建的DefautHandler数据结构并相应地生成输出。
我已经尝试了很多找到parse(is)
方法的源代码,但找不到它。在SAXParser类中,parse是一个抽象方法,因此无法找到我可以进一步了解源代码的实现类。
第二个但是很愚蠢的问题,我可以知道,当我们创建DefautHandler
实例时,该块内的方法是否被覆盖?在构造函数的块中,我们是否允许创建变量,就像我们创建了四个布尔变量一样?从未在Java中看到过这种方法。
任何人都可以帮助我....
谢谢
SAXParser是一个接口,有许多XML解析器可以实现此接口。如果你想知道它是如何工作的,你需要选择其中一个XML解析器 - 最容易访问的是Apache Xerces解析器。你可以从这里开始,但要注意阅读并不容易:
简单来说,解析器将寻找“<”,当它找到一个时,它将使用适当的参数调用提供的ContentHandler
的startElement()
方法。
实际上,为了成功地使用SAX解析器,你实际上并不需要理解它是如何在内部工作的。
你编写一个SAX ContentHandler(可能是DefaultHandler的扩展)是正确的,它涉及一种与你习惯的Java编程风格截然不同的Java编程风格。因为您的代码是通过回调处理事件,所以您不能像拥有主控制循环那样维护堆栈中的当前状态。相反,您必须考虑对诸如startElement()或characters()之类的方法的每次调用如何影响应用程序需要维护的当前状态,并确定如何修改保持此状态的数据结构。这是一种相当不同的编程方式,也是有些人说“拉”解析接口比“推”接口更容易使用的原因之一。