3) StAX 游标 API 示例
package com.onitroad.demo.stax; import java.io.File; import java.io.FileNotFoundException; import java.io.FileReader; import java.util.ArrayList; import java.util.List; import javax.xml.stream.XMLInputFactory; import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamReader; public class ReadXMLExample { public static void main(String[] args) throws FileNotFoundException, XMLStreamException { //All read employees objects will be added to this list List<Employee> employeeList = new ArrayList<>(); //Create Employee object. It will get all the data using setter methods. //And at last, it will stored in above 'employeeList' Employee employee = null; File file = new File("employees.xml"); XMLInputFactory factory = XMLInputFactory.newInstance(); XMLStreamReader streamReader = factory.createXMLStreamReader(new FileReader(file)); while(streamReader.hasNext()) { //Move to next event streamReader.next(); //Check if its 'START_ELEMENT' if(streamReader.getEventType() == XMLStreamReader.START_ELEMENT) { //employee tag - opened if(streamReader.getLocalName().equalsIgnoreCase("employee")) { //Create new employee object asap tag is open employee = new Employee(); //Read attributes within employee tag if(streamReader.getAttributeCount() > 0) { String id = streamReader.getAttributeValue(null,"id"); employee.setId(Integer.valueOf(id)); } } //Read name data if(streamReader.getLocalName().equalsIgnoreCase("name")) { employee.setName(streamReader.getElementText()); } //Read title data if(streamReader.getLocalName().equalsIgnoreCase("title")) { employee.setTitle(streamReader.getElementText()); } } //If employee tag is closed then add the employee object to list if(streamReader.getEventType() == XMLStreamReader.END_ELEMENT) { if(streamReader.getLocalName().equalsIgnoreCase("employee")) { employeeList.add(employee); } } } //Verify read data System.out.println(employeeList); } }
1) StAX 解析器
就像 SAX 解析器一样,StAX API 是为解析 XML 流而设计的。
区别在于:
- StAX 是一个“拉取”API。SAX 是一个“推送”API。
- StAX 可以进行 XML 读取和写入。SAX 只能做 XML 读取。
StAX 是一个拉取式 API。
这意味着我们必须自己将 StAX 解析器从 XML 文件中的一项移到另一项,就像使用标准的 Iterator
或者 JDBC ResultSet
一样。
然后,我们可以通过 StAX 解析器访问 XML 文件中遇到的每个此类“项目”的 XML 信息。
游标与迭代器
- 在读取 XML 文档时,迭代器读取器从它的
nextEvent()
调用返回一个 XML 事件对象。此事件提供有关我们遇到的 XML 标记类型(元素、文本、注释等)的信息。接收到的事件是不可变的,因此我们可以传递应用程序以安全地处理它。
XMLEventReader reader = ...; while(reader.hasNext()){ XMLEvent event = reader.nextEvent(); if(event.getEventType() == XMLEvent.START_ELEMENT){ //process data } //... more event types handled here... }
- 与迭代器不同,游标的工作方式类似于 JDBC 中的“结果集”。如果将光标移动到 XML 文档中的下一个元素。然后,我们可以直接在光标上调用方法以获取有关当前事件的更多信息。
XMLStreamReader streamReader = ...; while(streamReader.hasNext()){ int eventType = streamReader.next(); if(eventType == XMLStreamReader.START_ELEMENT){ System.out.println(streamReader.getLocalName()); } //... more event types handled here... }
on it road.com
2) StAX 迭代器 API 示例
下面演示了如何使用基于 StAX 迭代器的 API 来读取 XML 文档到对象。
测试 XML文件
<employees> <employee id="101"> <name>JackLi Gupta</name> <title>Author</title> </employee> <employee id="102"> <name>BobRobert Lara</name> <title>Cricketer</title> </employee> </employees>
使用 StAX Iterator 读取 XML
package com.onitroad.demo.stax; import java.io.File; import java.io.FileNotFoundException; import java.io.FileReader; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import javax.xml.namespace.QName; import javax.xml.stream.XMLEventReader; import javax.xml.stream.XMLInputFactory; import javax.xml.stream.XMLStreamException; import javax.xml.stream.events.Attribute; import javax.xml.stream.events.Characters; import javax.xml.stream.events.EndElement; import javax.xml.stream.events.StartElement; import javax.xml.stream.events.XMLEvent; public class ReadXMLExample { public static void main(String[] args) throws FileNotFoundException, XMLStreamException { File file = new File("employees.xml"); // Instance of the class which helps on reading tags XMLInputFactory factory = XMLInputFactory.newInstance(); // Initializing the handler to access the tags in the XML file XMLEventReader eventReader = factory.createXMLEventReader(new FileReader(file)); //All read employees objects will be added to this list List<Employee> employeeList = new ArrayList<>(); //Create Employee object. It will get all the data using setter methods. //And at last, it will stored in above 'employeeList' Employee employee = null; // Checking the availability of the next tag while (eventReader.hasNext()) { XMLEvent xmlEvent = eventReader.nextEvent(); if (xmlEvent.isStartElement()) { StartElement startElement = xmlEvent.asStartElement(); //As soo as employee tag is opened, create new Employee object if("employee".equalsIgnoreCase(startElement.getName().getLocalPart())) { employee = new Employee(); } //Read all attributes when start tag is being read @SuppressWarnings("unchecked") Iterator<Attribute> iterator = startElement.getAttributes(); while (iterator.hasNext()) { Attribute attribute = iterator.next(); QName name = attribute.getName(); if("id".equalsIgnoreCase(name.getLocalPart())) { employee.setId(Integer.valueOf(attribute.getValue())); } } //Now everytime content tags are found; //Move the iterator and read data switch (startElement.getName().getLocalPart()) { case "name": Characters nameDataEvent = (Characters) eventReader.nextEvent(); employee.setName(nameDataEvent.getData()); break; case "title": Characters titleDataEvent = (Characters) eventReader.nextEvent(); employee.setTitle(titleDataEvent.getData()); break; } } if (xmlEvent.isEndElement()) { EndElement endElement = xmlEvent.asEndElement(); //If employee tag is closed then add the employee object to list; //and be ready to read next employee data if("employee".equalsIgnoreCase(endElement.getName().getLocalPart())) { employeeList.add(employee); } } } System.out.println(employeeList); //Verify read data } }
StAX (Streaming API for XML) 提供了两种解析 XML 的方式,例如:基于游标的 API 和基于迭代器的 API。
日期:2020-09-17 00:10:13 来源:oir作者:oir