一、节点流和处理流的概念
节点流和处理流都是XML文档的数据流模型,其中节点流是基于文档模型的处理方式,处理流是基于事件模型的处理方式。
节点流可以看作是一条文档流水线,它将整个XML文档解析成为多个节点,每个节点都可以被程序直接处理和修改。
处理流是基于事件驱动的,它将整个XML文档解析成为多个事件流,程序需要监听并响应这些事件。
二、节点流和处理流的工作方式
节点流在处理XML文档时,会将整个文档解析成为一个文档节点,然后将每个元素、属性、文本和注释节点依次解析出来,并生成对应的DOM对象。程序可以直接对DOM对象进行增删改查等操作,最终将修改后的DOM对象重新序列化为XML文档。
处理流则是在解析XML文档时,程序需要注册事件处理器,监听事件流的变化,并对特定的事件响应不同的处理程序。例如,程序可以监听元素节点的开始标签和结束标签事件,在开始标签事件中生成元素节点对象,在结束标签事件中将元素节点对象添加到DOM树上。
三、节点流和处理流的优缺点
节点流的优点在于它为程序提供了完整的DOM树,程序可以直接对DOM进行增删改查等操作,非常方便。缺点在于,节点流在处理大型XML文档时可能会带来性能瓶颈,因为需要解析整个文档,生成完整的DOM树。
处理流的优点在于它可以在解析XML文档的同时实现事件处理,程序可以在不需要完整DOM树的情况下对XML文档进行处理,因此可以用于处理大型XML文档,提高性能。缺点在于处理流相对节点流来说,对于一些复杂操作可能不太方便,例如在事件处理过程中需要访问DOM树。
四、节点流和处理流的代码示例
节点流的代码示例:
import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; public class DOMParserExample { public static void main(String[] args) { try { File inputFile = new File("input.xml"); DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); Document doc = dBuilder.parse(inputFile); doc.getDocumentElement().normalize(); System.out.println("Root element :" + doc.getDocumentElement().getNodeName()); NodeList nList = doc.getElementsByTagName("student"); System.out.println("-----------------------"); for (int i = 0; i < nList.getLength(); i++) { Node nNode = nList.item(i); System.out.println("\nCurrent Element :" + nNode.getNodeName()); if (nNode.getNodeType() == Node.ELEMENT_NODE) { Element eElement = (Element) nNode; System.out.println("Student roll no : " + eElement.getAttribute("rollno")); System.out.println("First Name : " + eElement.getElementsByTagName("firstname").item(0).getTextContent()); System.out.println("Last Name : " + eElement.getElementsByTagName("lastname").item(0).getTextContent()); System.out.println("Nickname : " + eElement.getElementsByTagName("nickname").item(0).getTextContent()); System.out.println("Marks : " + eElement.getElementsByTagName("marks").item(0).getTextContent()); } } } catch (Exception e) { e.printStackTrace(); } } }
处理流的代码示例:
import javax.xml.parsers.*; import org.xml.sax.*; import org.xml.sax.helpers.*; public class SAXExample extends DefaultHandler { boolean bFirstName = false; boolean bLastName = false; boolean bNickName = false; boolean bMarks = false; public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { if (qName.equalsIgnoreCase("student")) { String rollNo = attributes.getValue("rollno"); System.out.println("Roll No : " + rollNo); } else if (qName.equalsIgnoreCase("firstname")) { bFirstName = true; } else if (qName.equalsIgnoreCase("lastname")) { bLastName = true; } else if (qName.equalsIgnoreCase("nickname")) { bNickName = true; } else if (qName.equalsIgnoreCase("marks")) { bMarks = true; } } public void endElement(String uri, String localName, String qName) throws SAXException { if (qName.equalsIgnoreCase("student")) { System.out.println("End Element : " + qName); } } public void characters(char ch[], int start, int length) throws SAXException { if (bFirstName) { System.out.println("First Name : " + new String(ch, start, length)); bFirstName = false; } else if (bLastName) { System.out.println("Last Name : " + new String(ch, start, length)); bLastName = false; } else if (bNickName) { System.out.println("Nick Name : " + new String(ch, start, length)); bNickName = false; } else if (bMarks) { System.out.println("Marks : " + new String(ch, start, length)); bMarks = false; } } public static void main(String[] args) { try { SAXParserFactory factory = SAXParserFactory.newInstance(); SAXParser saxParser = factory.newSAXParser(); SAXExample userhandler = new SAXExample(); saxParser.parse("input.xml", userhandler); } catch (Exception e) { e.printStackTrace(); } } }