Java SAX解析示例
时间:2020-01-09 10:36:30 来源:igfitidea点击:
在本文中,我将向我们展示一个示例,该示例说明如何使用SAX解析器解析XML文件,以及如何从解析的XML构建对象图。
这是我要解析的XML文档:
<driverVehicleInfo>
<vehicle>
<vehicleId>1</vehicleId>
<name>Limousine</name>
</vehicle>
<vehicle>
<vehicleId>2</vehicleId>
<name>Aston Martin</name>
</vehicle>
<vehicle>
<vehicleId>3</vehicleId>
<name>Bus</name>
</vehicle>
<driver>
<driverId>1</driverId>
<firstName>John</firstName>
<lastName>Doe</lastName>
<vehicleId>1</vehicleId>
<vehicleId>2</vehicleId>
</driver>
<driver>
<driverId>2</driverId>
<name>Joe Blocks</name>
<vehicleId>3</vehicleId>
</driver>
</driverVehicleInfo>
我想将这个XML结构解析为链接到"车辆"对象的"驱动程序"对象的对象结构。这是这两个类的定义。为了简化代码,我跳过了getter和setter方法。 toString()方法不是必需的。它们仅用于更轻松地打印示例中的结果。
public class Driver {
public String driverId = null;
public String name = null;
public List<Vehicle> vehicles = new ArrayList<Vehicle>();
public String toString() {
return this.driverId + " : " +
this.name + " : " +
this.vehicles;
}
}
public class Vehicle {
public String vehicleId = null;
public String name = null;
public String toString() {
return this.vehicleId + " : " +
this.name;
}
}
这是执行解析的DefaultHandler子类。请注意,它是如何使用两个堆栈来保持对XML元素的分析,并创建" Driver"和" Vehicle"对象。
还要注意,如果<vehicle>元素是在XML文件中的最后而不是第一个列出的,则此处理程序将无法工作。原因是,当处理<driver>元素时,他们希望已经填写了vehiclesMap。如果在<driver>元素之后列出了<vehicle>元素,则在处理<driver>元素时,vehiclesMap将为空。
我将把它作为练习,让我们了解其中发生的事情。它并不完全容易理解这一事实本身就是一个信息。 SAX可能很快,但是我们使用它编写的代码并不总是看起来太优雅。
package xml.sax;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
import java.util.*;
/**
*/
public class SaxHandler extends DefaultHandler {
public List<Driver> drivers = new ArrayList<Driver>();
public Map<String, Vehicle> vehicles = new HashMap<String, Vehicle>();
private Stack<String> elementStack = new Stack<String>();
private Stack<Object> objectStack = new Stack<Object>();
public void startElement(String uri, String localName,
String qName, Attributes attributes) throws SAXException {
this.elementStack.push(qName);
if("driver".equals(qName)){
Driver driver = new Driver();
this.objectStack.push(driver);
this.drivers.add(driver);
} else if("vehicle".equals(qName)){
this.objectStack.push(new Vehicle());
}
}
public void endElement(String uri, String localName,
String qName) throws SAXException {
this.elementStack.pop();
if("vehicle".equals(qName) || "driver".equals(qName)){
Object object = this.objectStack .pop();
if("vehicle".equals(qName)){
Vehicle vehicle = (Vehicle) object;
this.vehicles.put(vehicle.vehicleId, vehicle);
}
}
}
public void characters(char ch[], int start, int length)
throws SAXException {
String value = new String(ch, start, length).trim();
if(value.length() == 0) return; // ignore white space
if("driverId".equals(currentElement())){
Driver driver = (Driver) this.objectStack.peek();
driver.driverId = (driver.driverId != null ?
driver.driverId : "") + value;
} else if("name" .equals(currentElement()) &&
"driver".equals(currentElementParent())){
Driver driver = (Driver) this.objectStack.peek();
driver.name = (driver.name != null ?
driver.name : "") + value;
} else if("vehicleId".equals(currentElement()) &&
"driver" .equals(currentElementParent())){
Driver driver = (Driver) this.objectStack.peek();
Vehicle vehicle = this.vehicles.get(value);
if(vehicle != null) driver.vehicles.add(vehicle);
} else if("vehicleId".equals(currentElement()) &&
"vehicle" .equals(currentElementParent())){
Vehicle vehicle = (Vehicle) this.objectStack.peek();
vehicle.vehicleId = (vehicle.vehicleId != null ?
vehicle.vehicleId : "") + value;
} else if("name" .equals(currentElement()) &&
"vehicle".equals(currentElementParent())){
Vehicle vehicle = (Vehicle) this.objectStack.peek();
vehicle.name = (vehicle.name != null ? vehicle.name : "")
+ value;
}
}
private String currentElement() {
return this.elementStack.peek();
}
private String currentElementParent() {
if(this.elementStack.size() < 2) return null;
return this.elementStack.get(this.elementStack.size()-2);
}
}
这是运行示例的代码:
public class SaxParserExample {
public static void main (String argv []) {
SAXParserFactory factory = SAXParserFactory.newInstance();
try {
InputStream xmlInput =
new FileInputStream("data\sax-example.xml");
SAXParser saxParser = factory.newSAXParser();
SaxHandler handler = new SaxHandler();
saxParser.parse(xmlInput, handler);
for(Driver driver : handler.drivers){
System.out.println(driver);
}
} catch (Throwable err) {
err.printStackTrace ();
}
}
}
这是使用给定的XML文件,处理程序和运行程序示例产生的输出:
1 : John Doe : [1 : Limousine, 2 : Aston Martin] 2 : Joe Blocks : [3 : Bus]

