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>元素时,他们希望已经填写了vehicles
Map。如果在<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]