- Apache Xerces Tutorial
- Xerces Home
- XML Overview
- Xerces Environment Setup
- XML Parsers
- Xerces DOM Parser
- Xerces DOM Parser
- Parse XML Document
- Query XML Document
- Create XML Document
- Modify XML Document
- Xerces SAX Parser
- Xerces SAX Parser
- Parse XML Document
- Query XML Document
- Create XML Document
- Modify XML Document
- Xerces StAX Parser
- Xerces StAX Parser
- Parse XML Document
- Query XML Document
- Create XML Document
- Modify XML Document
- Xerces Useful Resources
- Xerces - Quick Guide
- Xerces - Useful Resources
- Xerces - Discussion
Apache Xerces - 快速指南
Apache Xerces - XML 概述
什么是XML?
XML 是一种简单的基于文本的语言,旨在以纯文本格式存储和传输数据。它代表可扩展标记语言。以下是 XML 的一些显着特征。
XML 是一种标记语言。
XML 是一种像 HTML 一样基于标签的语言。
XML 标签不像 HTML 那样是预定义的。
您可以定义自己的标签,这就是它被称为可扩展语言的原因。
XML 标签被设计为具有自描述性。
XML 是针对数据存储和传输的 W3C 建议。
例子
<?xml version = "1.0"?> <Class> <Name>First</Name> <Sections> <Section> <Name>A</Name> <Students> <Student>Rohan</Student> <Student>Mohan</Student> <Student>Sohan</Student> <Student>Lalit</Student> <Student>Vinay</Student> </Students> </Section> <Section> <Name>B</Name> <Students> <Student>Robert</Student> <Student>Julie</Student> <Student>Kalie</Student> <Student>Michael</Student> </Students> </Section> </Sections> </Class>
优点
以下是 XML 提供的优点 -
与技术无关- 作为纯文本,XML 与技术无关。它可以被任何技术用于数据存储和传输目的。
人类可读- XML 使用简单的文本格式。它是人类可读和可理解的。
可扩展- 在 XML 中,可以非常轻松地创建和使用自定义标签。
允许验证- 使用 XSD、DTD 和 XML 结构可以轻松验证。
缺点
以下是 XML 使用的缺点 -
冗余语法- 通常 XML 文件包含大量重复术语。
详细- 作为一种详细语言,XML 文件大小会增加传输和存储成本。
Apache Xerces - 环境设置
本章将引导您完成在基于 Windows 和 Linux 的系统上设置 Apache Xerces 的过程。只需几个简单的步骤,即可轻松安装 Apache Xerces 并与您当前的 Java 环境集成,无需任何复杂的设置过程。安装时需要用户管理。
系统要求
JDK | Java SE 2 JDK 1.5 或更高版本 |
---|---|
记忆 | 1 GB RAM(推荐) |
磁盘空间 | 无最低要求 |
操作系统版本 | Windows XP或以上、Linux |
现在让我们继续执行安装 Apache Xerces 的步骤。
第 1 步:验证您的 Java 安装
首先,您需要在系统上安装 Java 软件开发工具包 (SDK)。要验证这一点,请根据您正在使用的平台执行这两个命令中的任意一个。
如果 Java 安装成功,则会显示 Java 安装的当前版本和规格。下表给出了示例输出。
平台 | 命令 | 样本输出 |
---|---|---|
Windows | 打开命令控制台并输入 - java -version | Java 版本“1.7.0_60”Java (TM) SE 运行时环境(版本 1.7.0_60-b19) Java Hotspot (TM) 64 位服务器 VM(版本 24.60b09,混合模式) |
Linux | 打开命令终端并输入 - $java -version | Java 版本“1.7.0_25” 开放 JDK 运行时环境 (rhel-2.3.10.4.el6_4-x86_64) 开放 JDK 64 位服务器 VM(内部版本 23.7-b01,混合模式) |
我们假设本教程的读者在其系统上安装了 Java SDK 版本 1.7.0_60。
如果您没有 Java SDK,请从www.oracle.com/technetwork/java/javase/downloads/index.html下载其当前版本并进行安装。
第 2 步:设置 Java 环境
将环境变量 JAVA_HOME 设置为指向计算机上安装 Java 的基本目录位置。例如,
先生。 | 平台及描述 |
---|---|
1 | Windows 将 JAVA_HOME 设置为 C:\ProgramFiles\java\jdk1.7.0_60 |
2 | Linux 导出 JAVA_HOME = /usr/local/java-current |
将 Java 编译器位置的完整路径附加到系统路径。
先生。 | 平台及描述 |
---|---|
1 |
Windows 将字符串“C:\Program Files\Java\jdk1.7.0_60\bin”附加到系统变量 PATH 的末尾。 |
2 |
Linux 导出路径=$PATH:$JAVA_HOME/bin/ |
如上所述,从命令提示符处执行命令 java version。
第 3 步:安装 Apache Xerces 库
从https://xerces.apache.org/mirrors.cgi下载最新版本的 Apache Xerces ,并将其内容解压到一个文件夹,在该文件夹中所需的库可以链接到您的 Java 程序。让我们假设这些文件收集在C 盘上的文件夹 xerces-2_12_1。
将上图中突出显示的五个 jar 的完整路径添加到 CLASSPATH 中。
先生。 | 平台及描述 |
---|---|
1 | Windows 将以下字符串附加到用户变量 CLASSPATH 的末尾 - C:\xerces-2_12_1\resolver.jar; C:\xerces-2_12_1\serializer.jar; C:\xerces-2_12_1\xercesImpl.jar; C:\xerces-2_12_1\xercesSamples.jar; C:\xerces-2_12_1\xml-apis.jar; |
2 | Linux 导出 CLASSPATH = $CLASSPATH - /usr/share/xerces-2_12_1\resolver.jar; /usr/share/xerces-2_12_1\serializer.jar; /usr/share/xerces-2_12_1\xercesImpl.jar; /usr/share/xerces-2_12_1\xercesSamples.jar; /usr/share/xerces-2_12_1\xml-apis.jar; |
Apache Xerces - XML 解析器
什么是 Apache Xerces2?
Xerces2 是一个基于 Java 的处理器,为以下 XML 解析 API 标准提供标准接口和实现 -
文档对象模型 (DOM) 第 3 级
XML 的简单 API (SAX) 2.0.2
XML 流式 API (StAX) 1.0 事件 API
用于 XML 处理的 Java API (JAXP) 1.4
什么是 XML 解析?
解析 XML 是指通过 XML 文档以一种或另一种方式访问数据或修改数据。
什么是 XML 解析器?
XML 解析器提供了一种访问或修改 XML 文档中存在的数据的方法。Java 提供了多种解析 XML 文档的选项。以下是常用于解析 XML 文档的各种类型的解析器。
Dom Parser - 通过加载文档的完整内容并在内存中创建其完整的层次结构树来解析文档。
SAX 解析器- 根据基于事件的触发器解析文档。不将完整文档加载到内存中。
StAX Parser - 以与 SAX 解析器类似的方式解析文档,但以更有效的方式。
现在,我们将在后续章节中使用 Apache Xerces 库详细说明每个解析器。
Apache Xerces - DOM 解析器概述
文档对象模型是万维网联盟 (W3C) 的官方推荐。它定义了一个接口,使程序能够访问和更新 XML 文档的样式、结构和内容。支持 DOM 的 XML 解析器实现该接口。
什么时候使用?
您应该在以下情况下使用 DOM 解析器:
您需要了解很多有关文档结构的信息。
您需要移动文档的某些部分(例如,您可能想要对某些元素进行排序)。
您需要多次使用文档中的信息。
你得到什么?
当您使用 DOM 解析器解析 XML 文档时,您会得到一个包含文档所有元素的树结构。DOM 提供了多种可用于检查文档内容和结构的函数。
优点
DOM 是操作文档结构的通用接口。其设计目标之一是为一个 DOM 兼容解析器编写的 Java 代码应该可以在任何其他 DOM 兼容解析器上运行而无需更改。
DOM接口
DOM 定义了多个 Java 接口。以下是最常见的接口 -
Node - DOM 的基本数据类型。
元素- 您将处理的绝大多数对象都是元素。
Attr - 表示元素的属性。
文本- 元素或属性的实际内容。
文档- 代表整个 XML 文档。Document 对象通常称为 DOM 树。
常见的 DOM 方法
当您使用 DOM 时,有几种经常使用的方法 -
Document.getDocumentElement() - 返回文档的根元素。
Node.getFirstChild() - 返回给定节点的第一个子节点。
Node.getLastChild() - 返回给定节点的最后一个子节点。
Node.getNextSibling() - 这些方法返回给定节点的下一个兄弟节点。
Node.getPreviousSibling() - 这些方法返回给定节点的前一个兄弟节点。
Node.getAttribute(attrName) - 对于给定的节点,返回具有请求名称的属性。
DOM 解析器 - 解析 XML 文档
使用 DOM 的步骤
以下是使用 DOM 解析器解析文档时使用的步骤。
导入XML相关的包。
创建文档生成器
从文件或流创建文档
提取根元素
检查属性
检查子元素
导入XML相关包
import org.w3c.dom.*; import javax.xml.parsers.*; import java.io.*;
创建文档生成器
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); DocumentBuilder builder = factory.newDocumentBuilder();
从文件或流创建文档
StringBuilder xmlStringBuilder = new StringBuilder(); xmlStringBuilder.append("<?xml version = "1.0"?> <class> </class>"); ByteArrayInputStream input = new ByteArrayInputStream( xmlStringBuilder.toString().getBytes("UTF-8")); Document doc = builder.parse(input);
提取根元素
Element root = document.getDocumentElement();
检查属性
//returns specific attribute getAttribute("attributeName"); //returns a Map (table) of names/values getAttributes();
检查子元素
//returns a list of subelements of specified name getElementsByTagName("subelementName"); //returns a list of all child nodes getChildNodes();
演示示例
这是我们需要解析的输入 xml 文件 -
<?xml version = "1.0"?> <class> <student rollno = "393"> <firstname>Dinkar</firstname> <lastname>Kad</lastname> <nickname>Dinkar</nickname> <marks>85</marks> </student> <student rollno = "493"> <firstname>Vineet</firstname> <lastname>Gupta</lastname> <nickname>Vinni</nickname> <marks>95</marks> </student> <student rollno = "593"> <firstname>Jasvir</firstname> <lastname>Singh</lastname> <nickname>Jazz</nickname> <marks>90</marks> </student> </class>
演示示例
DomParserDemo.java
package com.tutorialspoint.xml; import java.io.File; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.DocumentBuilder; import org.w3c.dom.Document; import org.w3c.dom.NodeList; import org.w3c.dom.Node; import org.w3c.dom.Element; public class DomParserDemo { public static void main(String[] args){ try { File inputFile = new File("input.txt"); 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 temp = 0; temp < nList.getLength(); temp++) { Node nNode = nList.item(temp); 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("Nick Name : " + eElement .getElementsByTagName("nickname") .item(0) .getTextContent()); System.out.println("Marks : " + eElement .getElementsByTagName("marks") .item(0) .getTextContent()); } } } catch (Exception e) { e.printStackTrace(); } } }
上述程序将生成以下结果 -
Root element :class ---------------------------- Current Element :student Student roll no : 393 First Name : Dinkar Last Name : Kad Nick Name : Dinkar Marks : 85 Current Element :student Student roll no : 493 First Name : Vineet Last Name : Gupta Nick Name : Vinni Marks : 95 Current Element :student Student roll no : 593 First Name : Jasvir Last Name : Singh Nick Name : Jazz Marks : 90
DOM 解析器 - 查询 XML 文档
演示示例
这是我们需要查询的输入 xml 文件 -
<?xml version = "1.0"?> <cars> <supercars company = "Ferrari"> <carname type = "formula one">Ferarri 101</carname> <carname type = "sports car">Ferarri 201</carname> <carname type = "sports car">Ferarri 301</carname> </supercars> <supercars company = "Lamborgini"> <carname>Lamborgini 001</carname> <carname>Lamborgini 002</carname> <carname>Lamborgini 003</carname> </supercars> <luxurycars company = "Benteley"> <carname>Benteley 1</carname> <carname>Benteley 2</carname> <carname>Benteley 3</carname> </luxurycars> </cars>
演示示例
QueryXmlFileDemo.java
package com.tutorialspoint.xml; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.DocumentBuilder; import org.w3c.dom.Document; import org.w3c.dom.NodeList; import org.w3c.dom.Node; import org.w3c.dom.Element; import java.io.File; public class QueryXmlFileDemo { public static void main(String argv[]) { try { File inputFile = new File("input.txt"); DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); Document doc = dBuilder.parse(inputFile); doc.getDocumentElement().normalize(); System.out.print("Root element: "); System.out.println(doc.getDocumentElement().getNodeName()); NodeList nList = doc.getElementsByTagName("supercars"); System.out.println("----------------------------"); for (int temp = 0; temp < nList.getLength(); temp++) { Node nNode = nList.item(temp); System.out.println("\nCurrent Element :"); System.out.print(nNode.getNodeName()); if (nNode.getNodeType() == Node.ELEMENT_NODE) { Element eElement = (Element) nNode; System.out.print("company : "); System.out.println(eElement.getAttribute("company")); NodeList carNameList = eElement.getElementsByTagName("carname"); for (int count = 0; count < carNameList.getLength(); count++) { Node node1 = carNameList.item(count); if (node1.getNodeType() == node1.ELEMENT_NODE) { Element car = (Element) node1; System.out.print("car name : "); System.out.println(car.getTextContent()); System.out.print("car type : "); System.out.println(car.getAttribute("type")); } } } } } catch (Exception e) { e.printStackTrace(); } } }
上述程序将生成以下结果 -
Root element :cars ---------------------------- Current Element :supercars company : Ferrari car name : Ferarri 101 car type : formula one car name : Ferarri 201 car type : sports car car name : Ferarri 301 car type : sports car Current Element :supercars company : Lamborgini car name : Lamborgini 001 car type : car name : Lamborgini 002 car type : car name : Lamborgini 003 car type :
DOM 解析器 - 创建 XML 文档
演示示例
这是我们需要创建的 XML -
<?xml version = "1.0" encoding = "UTF-8" standalone = "no"?> <cars><supercars company = "Ferrari"> <carname type = "formula one">Ferrari 101</carname> <carname type = "sports">Ferrari 202</carname> </supercars></cars>
演示示例
CreateXmlFileDemo.java
package com.tutorialspoint.xml; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.DocumentBuilder; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; import org.w3c.dom.Attr; import org.w3c.dom.Document; import org.w3c.dom.Element; import java.io.File; public class CreateXmlFileDemo { public static void main(String argv[]) { try { DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); Document doc = dBuilder.newDocument(); // root element Element rootElement = doc.createElement("cars"); doc.appendChild(rootElement); // supercars element Element supercar = doc.createElement("supercars"); rootElement.appendChild(supercar); // setting attribute to element Attr attr = doc.createAttribute("company"); attr.setValue("Ferrari"); supercar.setAttributeNode(attr); // carname element Element carname = doc.createElement("carname"); Attr attrType = doc.createAttribute("type"); attrType.setValue("formula one"); carname.setAttributeNode(attrType); carname.appendChild( doc.createTextNode("Ferrari 101")); supercar.appendChild(carname); Element carname1 = doc.createElement("carname"); Attr attrType1 = doc.createAttribute("type"); attrType1.setValue("sports"); carname1.setAttributeNode(attrType1); carname1.appendChild( doc.createTextNode("Ferrari 202")); supercar.appendChild(carname1); // write the content into xml file TransformerFactory transformerFactory = TransformerFactory.newInstance(); Transformer transformer = transformerFactory.newTransformer(); DOMSource source = new DOMSource(doc); StreamResult result = new StreamResult(new File("C:\\cars.xml")); transformer.transform(source, result); // Output to console for testing StreamResult consoleResult = new StreamResult(System.out); transformer.transform(source, consoleResult); } catch (Exception e) { e.printStackTrace(); } } }
上述程序将生成以下结果 -
<?xml version = "1.0" encoding = "UTF-8" standalone = "no"?> <cars><supercars company = "Ferrari"> <carname type = "formula one">Ferrari 101</carname> <carname type = "sports">Ferrari 202</carname> </supercars></cars>
DOM 解析器 - 修改 XML 文档
演示示例
这是我们需要修改的输入 xml 文件 -
<?xml version = "1.0" encoding = "UTF-8" standalone = "no"?> <cars> <supercars company = "Ferrari"> <carname type = "formula one">Ferrari 101</carname> <carname type = "sports">Ferrari 202</carname> </supercars> <luxurycars company = "Benteley"> <carname>Benteley 1</carname> <carname>Benteley 2</carname> <carname>Benteley 3</carname> </luxurycars> </cars>
演示示例
修改XmlFileDemo.java
package com.tutorialspoint.xml; import java.io.File; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.NamedNodeMap; import org.w3c.dom.Node; import org.w3c.dom.NodeList; public class ModifyXmlFileDemo { public static void main(String argv[]) { try { File inputFile = new File("input.txt"); DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance(); DocumentBuilder docBuilder = docFactory.newDocumentBuilder(); Document doc = docBuilder.parse(inputFile); Node cars = doc.getFirstChild(); Node supercar = doc.getElementsByTagName("supercars").item(0); // update supercar attribute NamedNodeMap attr = supercar.getAttributes(); Node nodeAttr = attr.getNamedItem("company"); nodeAttr.setTextContent("Lamborigini"); // loop the supercar child node NodeList list = supercar.getChildNodes(); for (int temp = 0; temp < list.getLength(); temp++) { Node node = list.item(temp); if (node.getNodeType() == Node.ELEMENT_NODE) { Element eElement = (Element) node; if ("carname".equals(eElement.getNodeName())){ if("Ferrari 101".equals(eElement.getTextContent())){ eElement.setTextContent("Lamborigini 001"); } if("Ferrari 202".equals(eElement.getTextContent())) eElement.setTextContent("Lamborigini 002"); } } } NodeList childNodes = cars.getChildNodes(); for(int count = 0; count < childNodes.getLength(); count++){ Node node = childNodes.item(count); if("luxurycars".equals(node.getNodeName())) cars.removeChild(node); } // write the content on console TransformerFactory transformerFactory = TransformerFactory.newInstance(); Transformer transformer = transformerFactory.newTransformer(); DOMSource source = new DOMSource(doc); System.out.println("-----------Modified File-----------"); StreamResult consoleResult = new StreamResult(System.out); transformer.transform(source, consoleResult); } catch (Exception e) { e.printStackTrace(); } } }
上述程序将生成以下结果 -
-----------Modified File----------- <?xml version = "1.0" encoding = "UTF-8" standalone = "no"?> <cars> <supercars company = "Lamborigini"> <carname type = "formula one">Lamborigini 001</carname> <carname type = "sports">Lamborigini 002</carname> </supercars></cars>
SAX 解析器 - 概述
SAX(XML 的简单 API)是一个基于事件的 xml 文档解析器。与 DOM 解析器不同,SAX 解析器不创建解析树。SAX 是 XML 的流式接口,这意味着使用 SAX 的应用程序会按顺序接收有关正在处理的 XML 文档(元素和属性)的事件通知,从文档顶部开始,到文档结束为止。根元素。
从上到下读取 XML 文档,识别构成格式良好的 XML 文档的标记。
令牌的处理顺序与它们在文档中出现的顺序相同。
报告应用程序、解析器在出现时遇到的标记的性质。
应用程序提供必须向解析器注册的“事件”处理程序。
识别令牌后,将使用相关信息调用处理程序中的回调方法。
什么时候使用?
您应该在以下情况下使用 SAX 解析器:
您可以从上到下以线性方式处理 XML 文档。
该文档没有深度嵌套。
您正在处理一个非常大的 XML 文档,其中的 DOM 树将消耗大量内存。典型的 DOM 实现使用 10 个字节的内存来表示 1 个字节的 XML。
所要解决的问题只涉及XML文档的一部分。
解析器一看到数据就可用,因此 SAX 非常适合通过流到达的 XML 文档。
SAX 的缺点
我们无法随机访问 XML 文档,因为它是以向前方式处理的。
如果您需要跟踪解析器已看到的数据或更改项目的顺序,则必须自行编写代码并存储数据。
内容处理器接口
该接口指定 SAX 解析器用来通知应用程序它已看到的 XML 文档的组件的回调方法。
void startDocument() - 在文档的开头调用。
void endDocument() - 在文档的开头调用。
void startElement(String uri, String localName, String qName, Attributes atts) - 在元素的开头调用。
void endElement(String uri, String localName,String qName) - 在元素末尾调用。
void strings(char[] ch, int start, int length) - 遇到字符数据时调用。
void ignorableWhitespace( char[] ch, int start, int length) - 当存在 DTD 且遇到可忽略的空白时调用。
voidprocessingInstruction(String target, String data) - 当识别处理指令时调用。
void setDocumentLocator(Locator locator)) - 提供可用于识别文档中位置的定位器。
void SkippedEntity(String name) - 当遇到未解析的实体时调用。
void startPrefixMapping(String prefix, String uri) - 定义新的命名空间映射时调用。
void endPrefixMapping(String prefix) - 当命名空间定义结束其范围时调用。
属性接口
该接口指定处理连接到元素的属性的方法。
int getLength() - 返回属性的数量。
字符串 getQName(int 索引)
字符串 getValue(int 索引)
字符串 getValue(字符串 qname)
SAX 解析器 - 解析 XML 文档
演示示例
这是我们需要解析的输入 xml 文件 -
<?xml version = "1.0"?> <class> <student rollno = "393"> <firstname>Dinkar</firstname> <lastname>Kad</lastname> <nickname>Dinkar</nickname> <marks>85</marks> </student> <student rollno = "493"> <firstname>Vineet</firstname> <lastname>Gupta</lastname> <nickname>Vinni</nickname> <marks>95</marks> </student> <student rollno = "593"> <firstname>Jasvir</firstname> <lastname>Singh</lastname> <nickname>Jazz</nickname> <marks>90</marks> </student> </class>
用户处理程序.java
package com.tutorialspoint.xml; import org.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.helpers.DefaultHandler; public class UserHandler extends DefaultHandler { boolean bFirstName = false; boolean bLastName = false; boolean bNickName = false; boolean bMarks = false; @Override 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; } } @Override public void endElement(String uri, String localName, String qName) throws SAXException { if (qName.equalsIgnoreCase("student")) { System.out.println("End Element :" + qName); } } @Override 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; } } }
SAXParserDemo.java
package com.tutorialspoint.xml; import java.io.File; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import org.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.helpers.DefaultHandler; public class SAXParserDemo { public static void main(String[] args){ try { File inputFile = new File("input.txt"); SAXParserFactory factory = SAXParserFactory.newInstance(); SAXParser saxParser = factory.newSAXParser(); UserHandler userhandler = new UserHandler(); saxParser.parse(inputFile, userhandler); } catch (Exception e) { e.printStackTrace(); } } } class UserHandler extends DefaultHandler { boolean bFirstName = false; boolean bLastName = false; boolean bNickName = false; boolean bMarks = false; @Override 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; } } @Override public void endElement(String uri, String localName, String qName) throws SAXException { if (qName.equalsIgnoreCase("student")) { System.out.println("End Element :" + qName); } } @Override 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; } } }
上述程序将生成以下结果 -
Roll No : 393 First Name: Dinkar Last Name: Kad Nick Name: Dinkar Marks: 85 End Element :student Roll No : 493 First Name: Vineet Last Name: Gupta Nick Name: Vinni Marks: 95 End Element :student Roll No : 593 First Name: Jasvir Last Name: Singh Nick Name: Jazz Marks: 90 End Element :student
SAX 解析器 - 查询 XML 文档
演示示例
这是我们需要查询卷号的输入文本文件:393 -
<?xml version = "1.0"?> <class> <student rollno = "393"> <firstname>Dinkar</firstname> <lastname>Kad</lastname> <nickname>Dinkar</nickname> <marks>85</marks> </student> <student rollno = "493"> <firstname>Vineet</firstname> <lastname>Gupta</lastname> <nickname>Vinni</nickname> <marks>95</marks> </student> <student rollno = "593"> <firstname>Jasvir</firstname> <lastname>Singh</lastname> <nickname>Jazz</nickname> <marks>90</marks> </student> </class>
用户处理程序.java
package com.tutorialspoint.xml; import org.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.helpers.DefaultHandler; public class UserHandler extends DefaultHandler { boolean bFirstName = false; boolean bLastName = false; boolean bNickName = false; boolean bMarks = false; String rollNo = null; @Override public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { if (qName.equalsIgnoreCase("student")) { rollNo = attributes.getValue("rollno"); } if(("393").equals(rollNo) && qName.equalsIgnoreCase("student")){ System.out.println("Start Element :" + qName); } 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; } } @Override public void endElement(String uri, String localName, String qName) throws SAXException { if (qName.equalsIgnoreCase("student")) { if(("393").equals(rollNo) && qName.equalsIgnoreCase("student")) System.out.println("End Element :" + qName); } } @Override public void characters(char ch[], int start, int length) throws SAXException { if (bFirstName && ("393").equals(rollNo)) { //age element, set Employee age System.out.println("First Name: " + new String(ch, start, length)); bFirstName = false; } else if (bLastName && ("393").equals(rollNo)) { System.out.println("Last Name: " + new String(ch, start, length)); bLastName = false; } else if (bNickName && ("393").equals(rollNo)) { System.out.println("Nick Name: " + new String(ch, start, length)); bNickName = false; } else if (bMarks && ("393").equals(rollNo)) { System.out.println("Marks: " + new String(ch, start, length)); bMarks = false; } } }
SAXQueryDemo.java
package com.tutorialspoint.xml; import java.io.File; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import org.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.helpers.DefaultHandler; public class SAXQueryDemo { public static void main(String[] args){ try { File inputFile = new File("input.txt"); SAXParserFactory factory = SAXParserFactory.newInstance(); SAXParser saxParser = factory.newSAXParser(); UserHandler userhandler = new UserHandler(); saxParser.parse(inputFile, userhandler); } catch (Exception e) { e.printStackTrace(); } } } class UserHandler extends DefaultHandler { boolean bFirstName = false; boolean bLastName = false; boolean bNickName = false; boolean bMarks = false; String rollNo = null; @Override public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { if (qName.equalsIgnoreCase("student")) { rollNo = attributes.getValue("rollno"); } if(("393").equals(rollNo) && qName.equalsIgnoreCase("student")){ System.out.println("Start Element :" + qName); } 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; } } @Override public void endElement(String uri, String localName, String qName) throws SAXException { if (qName.equalsIgnoreCase("student")) { if(("393").equals(rollNo) && qName.equalsIgnoreCase("student")) System.out.println("End Element :" + qName); } } @Override public void characters(char ch[], int start, int length) throws SAXException { if (bFirstName && ("393").equals(rollNo)) { //age element, set Employee age System.out.println("First Name: " + new String(ch, start, length)); bFirstName = false; } else if (bLastName && ("393").equals(rollNo)) { System.out.println("Last Name: " + new String(ch, start, length)); bLastName = false; } else if (bNickName && ("393").equals(rollNo)) { System.out.println("Nick Name: " + new String(ch, start, length)); bNickName = false; } else if (bMarks && ("393").equals(rollNo)) { System.out.println("Marks: " + new String(ch, start, length)); bMarks = false; } } }
上述程序将生成以下结果 -
Start Element :student First Name: Dinkar Last Name: Kad Nick Name: Dinkar Marks: 85 End Element :student
SAX 解析器 - 创建 XML 文档
使用 StAX 解析器创建 XML 比使用 SAX 解析器更好。请参阅 Java StAX 解析器部分以了解相同内容。
SAX 解析器 - 修改 XML 文档
演示示例
这是我们需要通过在</marks> 标记末尾附加<Result>Pass<Result/>来修改的输入 xml 文件。
<?xml version = "1.0"?> <class> <student rollno = "393"> <firstname>Dinkar</firstname> <lastname>Kad</lastname> <nickname>Dinkar</nickname> <marks>85</marks> </student> <student rollno = "493"> <firstname>Vineet</firstname> <lastname>Gupta</lastname> <nickname>Vinni</nickname> <marks>95</marks> </student> <student rollno = "593"> <firstname>Jasvir</firstname> <lastname>Singh</lastname> <nickname>Jazz</nickname> <marks>90</marks> </student> </class>
SAXModifyDemo.java
package com.tutorialspoint.xml; import java.io.*; import org.xml.sax.*; import javax.xml.parsers.*; import org.xml.sax.helpers.DefaultHandler; public class SAXModifyDemo extends DefaultHandler { static String displayText[] = new String[1000]; static int numberLines = 0; static String indentation = ""; public static void main(String args[]) { try { File inputFile = new File("input.txt"); SAXParserFactory factory = SAXParserFactory.newInstance(); SAXModifyDemo obj = new SAXModifyDemo(); obj.childLoop(inputFile); FileWriter filewriter = new FileWriter("newfile.xml"); for(int loopIndex = 0; loopIndex < numberLines; loopIndex++){ filewriter.write(displayText[loopIndex].toCharArray()); filewriter.write('\n'); System.out.println(displayText[loopIndex].toString()); } filewriter.close(); } catch (Exception e) { e.printStackTrace(System.err); } } public void childLoop(File input){ DefaultHandler handler = this; SAXParserFactory factory = SAXParserFactory.newInstance(); try { SAXParser saxParser = factory.newSAXParser(); saxParser.parse(input, handler); } catch (Throwable t) {} } public void startDocument() { displayText[numberLines] = indentation; displayText[numberLines] += "<?xml version=\"1.0\" encoding=\""+ "UTF-8" + "\"?>"; numberLines++; } public void processingInstruction(String target, String data) { displayText[numberLines] = indentation; displayText[numberLines] += "<?"; displayText[numberLines] += target; if (data != null && data.length() > 0) { displayText[numberLines] += ' '; displayText[numberLines] += data; } displayText[numberLines] += "?>"; numberLines++; } public void startElement(String uri, String localName, String qualifiedName, Attributes attributes) { displayText[numberLines] = indentation; indentation += " "; displayText[numberLines] += '<'; displayText[numberLines] += qualifiedName; if (attributes != null) { int numberAttributes = attributes.getLength(); for (int loopIndex = 0; loopIndex < numberAttributes; loopIndex++){ displayText[numberLines] += ' '; displayText[numberLines] += attributes.getQName(loopIndex); displayText[numberLines] += "=\""; displayText[numberLines] += attributes.getValue(loopIndex); displayText[numberLines] += '"'; } } displayText[numberLines] += '>'; numberLines++; } public void characters(char characters[], int start, int length) { String characterData = (new String(characters, start, length)).trim(); if(characterData.indexOf("\n") < 0 && characterData.length() > 0) { displayText[numberLines] = indentation; displayText[numberLines] += characterData; numberLines++; } } public void endElement(String uri, String localName, String qualifiedName) { indentation = indentation.substring(0, indentation.length() - 4); displayText[numberLines] = indentation; displayText[numberLines] += "</"; displayText[numberLines] += qualifiedName; displayText[numberLines] += '>'; numberLines++; if (qualifiedName.equals("marks")) { startElement("", "Result", "Result", null); characters("Pass".toCharArray(), 0, "Pass".length()); endElement("", "Result", "Result"); } } }
上述程序将生成以下结果 -
<?xml version = "1.0" encoding = "UTF-8"?> <class> <student rollno = "393"> <firstname> Dinkar </firstname> <lastname> Kad </lastname> <nickname> Dinkar </nickname> <marks> 85 </marks> <Result> Pass </Result> </student> <student rollno = "493"> <firstname> Vineet </firstname> <lastname> Gupta </lastname> <nickname> Vinni </nickname> <marks> 95 </marks> <Result> Pass </Result> </student> <student rollno = "593"> <firstname> Jasvir </firstname> <lastname> Singh </lastname> <nickname> Jazz </nickname> <marks> 90 </marks> <Result> Pass </Result> </student> </class>
StAX 解析器 - 概述
StAX 是一个基于 JAVA 的 API,用于以与 SAX 解析器类似的方式解析 XML 文档。但这两个 API 之间有两个主要区别 -
StAX 是 PULL API,而 SAX 是 PUSH API。这意味着在 StAX 解析器的情况下,客户端应用程序需要在需要时要求 StAX 解析器从 XML 中获取信息,但在 SAX 解析器的情况下,当 SAX 解析器通知客户端应用程序该信息时,客户端应用程序需要获取信息可用。
StAX API 可以读取和写入 XML 文档。使用SAX API,xml只能读取。
以下是 StAX API 的功能 -
从上到下读取 XML 文档,识别构成格式良好的 XML 文档的标记。
令牌的处理顺序与它们在文档中出现的顺序相同。
向应用程序报告解析器在出现时遇到的标记的性质。
应用程序提供了一个“事件”读取器,它充当迭代器并迭代事件以获取所需的信息。另一种可用的读取器是“光标”读取器,它充当指向 xml 节点的指针。
当事件被识别时,可以从事件对象中检索 xml 元素并进行进一步处理。
什么时候使用?
您应该在以下情况下使用 StAX 解析器:
您可以从上到下以线性方式处理 XML 文档。
该文档没有深度嵌套。
您正在处理一个非常大的 XML 文档,其中的 DOM 树将消耗太多内存。典型的 DOM 实现使用 10 个字节的内存来表示 1 个字节的 XML。
所要解决的问题只涉及XML文档的一部分。
解析器一看到数据就可用,因此 StAX 非常适合通过流到达的 XML 文档。
SAX 的缺点
我们无法随机访问 XML 文档,因为它是以只进方式处理的。
如果您需要跟踪解析器已看到的数据或更改项目的顺序,则必须自行编写代码并存储数据。
XMLEventReader 类
此类提供事件迭代器,可用于在解析 XML 文档时迭代事件
StartElement asStartElement() - 用于检索元素的值和属性。
EndElement asEndElement() - 在元素末尾调用。
字符 asCharacters() - 可用于获取字符,例如 CDATA、空格等。
XMLEventWriter 类
该接口指定创建事件的方法。
add(Event event) - 将包含元素的事件添加到 XML。
XMLStreamReader 类
此类提供事件迭代器,可用于在解析 XML 文档时迭代事件
int next() - 用于检索下一个事件。
boolean hasNext() - 用于检查进一步的事件是否存在
String getText() - 用于获取元素的文本
String getLocalName() - 用于获取元素的名称
XMLStreamWriter 类
该接口指定创建事件的方法。
writeStartElement(String localName) - 添加给定名称的开始元素。
writeEndElement(String localName) - 添加给定名称的结束元素。
writeAttribute(String localName, String value) - 将属性写入元素。
StAX 解析器 - 解析 XML 文档
演示示例
这是我们需要解析的输入 xml 文件 -
<?xml version = "1.0"?> <class> <student rollno = "393"> <firstname>Dinkar</firstname> <lastname>Kad</lastname> <nickname>Dinkar</nickname> <marks>85</marks> </student> <student rollno = "493"> <firstname>Vineet</firstname> <lastname>Gupta</lastname> <nickname>Vinni</nickname> <marks>95</marks> </student> <student rollno = "593"> <firstname>Jasvir</firstname> <lastname>Singh</lastname> <nickname>Jazz</nickname> <marks>90</marks> </student> </class>
StAXParserDemo.java
package com.tutorialspoint.xml; import java.io.FileNotFoundException; import java.io.FileReader; import java.util.Iterator; import javax.xml.stream.XMLEventReader; import javax.xml.stream.XMLInputFactory; import javax.xml.stream.XMLStreamConstants; 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 StAXParserDemo { public static void main(String[] args) { boolean bFirstName = false; boolean bLastName = false; boolean bNickName = false; boolean bMarks = false; try { XMLInputFactory factory = XMLInputFactory.newInstance(); XMLEventReader eventReader = factory.createXMLEventReader(new FileReader("input.txt")); while(eventReader.hasNext()){ XMLEvent event = eventReader.nextEvent(); switch(event.getEventType()){ case XMLStreamConstants.START_ELEMENT: StartElement startElement = event.asStartElement(); String qName = startElement.getName().getLocalPart(); if (qName.equalsIgnoreCase("student")) { System.out.println("Start Element : student"); Iterator<Attribute> attributes = startElement.getAttributes(); String rollNo = attributes.next().getValue(); 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; } break; case XMLStreamConstants.CHARACTERS: Characters characters = event.asCharacters(); if(bFirstName){ System.out.println("First Name: " + characters.getData()); bFirstName = false; } if(bLastName){ System.out.println("Last Name: " + characters.getData()); bLastName = false; } if(bNickName){ System.out.println("Nick Name: " + characters.getData()); bNickName = false; } if(bMarks){ System.out.println("Marks: " + characters.getData()); bMarks = false; } break; case XMLStreamConstants.END_ELEMENT: EndElement endElement = event.asEndElement(); if(endElement.getName().getLocalPart().equalsIgnoreCase("student")){ System.out.println("End Element : student"); System.out.println(); } break; } } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (XMLStreamException e) { e.printStackTrace(); } } }
上述程序将生成以下结果 -
Start Element : student Roll No : 393 First Name: Dinkar Last Name: Kad Nick Name: Dinkar Marks: 85 End Element : student Start Element : student Roll No : 493 First Name: Vineet Last Name: Gupta Nick Name: Vinni Marks: 95 End Element : student Start Element : student Roll No : 593 First Name: Jasvir Last Name: Singh Nick Name: Jazz Marks: 90 End Element : student
StAX 解析器 - 查询 XML 文档
演示示例
这是我们需要解析的输入 xml 文件 -
<?xml version = "1.0"?> <class> <student rollno = "393"> <firstname>Dinkar</firstname> <lastname>Kad</lastname> <nickname>Dinkar</nickname> <marks>85</marks> </student> <student rollno = "493"> <firstname>Vineet</firstname> <lastname>Gupta</lastname> <nickname>Vinni</nickname> <marks>95</marks> </student> <student rollno = "593"> <firstname>Jasvir</firstname> <lastname>Singh</lastname> <nickname>Jazz</nickname> <marks>90</marks> </student> </class>
StAXParserDemo.java
package com.tutorialspoint.xml; import java.io.FileNotFoundException; import java.io.FileReader; import java.util.Iterator; import javax.xml.stream.XMLEventReader; import javax.xml.stream.XMLInputFactory; import javax.xml.stream.XMLStreamConstants; 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 StAXQueryDemo { public static void main(String[] args) { boolean bFirstName = false; boolean bLastName = false; boolean bNickName = false; boolean bMarks = false; boolean isRequestRollNo = false; try { XMLInputFactory factory = XMLInputFactory.newInstance(); XMLEventReader eventReader = factory.createXMLEventReader( new FileReader("input.txt")); String requestedRollNo = "393"; while(eventReader.hasNext()){ XMLEvent event = eventReader.nextEvent(); switch(event.getEventType()){ case XMLStreamConstants.START_ELEMENT: StartElement startElement = event.asStartElement(); String qName = startElement.getName().getLocalPart(); if (qName.equalsIgnoreCase("student")) { Iterator<Attribute> attributes = startElement.getAttributes(); String rollNo = attributes.next().getValue(); if(rollNo.equalsIgnoreCase(requestedRollNo)){ System.out.println("Start Element : student"); System.out.println("Roll No : " + rollNo); isRequestRollNo = true; } } 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; } break; case XMLStreamConstants.CHARACTERS: Characters characters = event.asCharacters(); if(bFirstName && isRequestRollNo){ System.out.println("First Name: " + characters.getData()); bFirstName = false; } if(bLastName && isRequestRollNo){ System.out.println("Last Name: " + characters.getData()); bLastName = false; } if(bNickName && isRequestRollNo){ System.out.println("Nick Name: " + characters.getData()); bNickName = false; } if(bMarks && isRequestRollNo){ System.out.println("Marks: " + characters.getData()); bMarks = false; } break; case XMLStreamConstants.END_ELEMENT: EndElement endElement = event.asEndEle