Java Xml 简明教程

Java XML - Quick Guide

Java XML - Overview

What is XML?

XML 是一种简单的基于文本的语言,旨在以纯文本格式存储和传输数据。它代表可扩展标记语言。以下是 XML 的一些显著功能。

  1. XML 是一种标记语言。

  2. XML 是一种基于标记的语言,如 HTML。

  3. XML 标记不是预定义的,如 HTML。

  4. 您可定义自己的标记,这就是为什么它被称为可扩展语言。

  5. XML 标记被设计为自描述的。

  6. XML 是 W3C 对数据存储和数据传输的建议。

Example

<?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>

Advantages

以下 XML 提供的优点 −

  1. Technology agnostic − 作为纯文本,XML 与技术无关。它可以被任何技术用于数据存储和数据传输目的。

  2. Human readable − XML 使用简单的文本格式。它具有可读性和可理解性。

  3. Extensible − 在 XML 中,可以非常轻松地创建和使用自定义标签。

  4. Allow Validation − 使用 XSD、DTD 和 XML 结构可以轻松验证。

Disadvantages

以下是使用 XML 的缺点 −

  1. Redundant Syntax − 通常 XML 文件中包含大量重复的术语。

  2. Verbose − 作为一种冗长语言,XML 文件大小会增加传输和存储成本。

Java XML - Parsers

XML 解析是指遍历 XML 文档以访问或修改数据。

What is XML Parser?

XML 解析器提供了一种在 XML 文档中访问或修改数据的方法。Java 提供了多种选项来解析 XML 文档。以下是通常用于解析 XML 文档的各种类型的解析器。

  1. Dom Parser − 通过加载文档的完整内容并创建其在内存中的完整层次结构树来解析 XML 文档。

  2. SAX Parser − 根据基于事件的触发器来解析 XML 文档。不会将完整文档加载到内存中。

  3. JDOM Parser − 以类似于 DOM 解析器的方式解析 XML 文档,但更简单。

  4. StAX Parser − 以类似于 SAX 解析器的方式来解析 XML 文档,但效果更高。

  5. XPath Parser − 根据表达式解析 XML 文档,并且在 conjunction with XSLT 中得到了广泛使用。

  6. DOM4J Parser − 使用 Java Collections Framework 来解析 XML、XPath 和 XSLT 的 Java 库。它提供对 DOM、SAX 和 JAXP 的支持。

可以使用 JAXB 和 XSLT API 来以面向对象的方式来处理 XML 解析。我们将在本教程的后续章节中详细阐述每个解析器。

Java DOM Parser - Overview

文档对象模型 (DOM) 是万维网联盟 (W3C) 的官方推荐。它定义了一个接口,让程序能够访问并更新 XML 文档的样式、结构和内容。支持 DOM 的 XML 解析器会实现这个接口。

When to Use?

你应在下列情况下使用 DOM 解析器:

  1. 您需要充分理解文档的结构。

  2. - 您需要移动 XML 文档的各个部分(例如,您可能需要对某些元素进行排序)。

  3. - 您需要多次使用 XML 文档中的信息。

What You Get?

使用 DOM 解析器解析 XML 文档时,你会得到一个包含你的文档所有元素的树形结构。DOM 提供了各种函数让你能够检查文档的内容和结构。

Advantages

DOM 是用于操作文档结构的一个通用接口。它的设计目标之一是为某个 DOM 兼容解析器编写的 Java 代码应该可以在其他任何 DOM 兼容解析器上运行,而无需进行任何修改。

DOM interfaces

DOM 定义了若干 Java 接口。这里是最常见的接口 −

  1. Node − DOM 的基本数据类型。

  2. Element − 你要处理的对象的最大部分是元素。

  3. Attr − 表示元素的一个属性。

  4. Text − 元素或属性的实际内容。

  5. Document − 表示整个 XML 文档。文档对象通常称为 DOM 树。

Common DOM methods

当你使用 DOM 时,你会经常用到以下几个方法 −

  1. Document.getDocumentElement() − 返回文档的根元素。

  2. Node.getFirstChild() − 返回给定节点的第一个子代。

  3. Node.getLastChild() − 返回给定节点的最后一个子代。

  4. Node.getNextSibling() − 这些方法返回给定节点的下一个同级。

  5. Node.getPreviousSibling() − 这些方法返回给定节点的前一个同级。

  6. Node.getAttribute(attrName) - 对于给定的节点,它返回具有请求名称的属性。

Java DOM Parser - Parse XML Document

Steps to Using JDOM

以下是使用 JDOM 解析器解析文档时使用的步骤。

  1. Import XML-related packages.

  2. Create a DocumentBuilder

  3. 从文件或流创建一个文档

  4. Extract the root element

  5. Examine attributes

  6. Examine sub-elements

import org.w3c.dom.*;
import javax.xml.parsers.*;
import java.io.*;

Create a DocumentBuilder

DocumentBuilderFactory factory =
DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();

Create a Document from a file or stream

StringBuilder xmlStringBuilder = new StringBuilder();
xmlStringBuilder.append("<?xml version="1.0"?>  ");
ByteArrayInputStream input = new ByteArrayInputStream(
   xmlStringBuilder.toString().getBytes("UTF-8"));
Document doc = builder.parse(input);

Extract the root element

Element root = document.getDocumentElement();

Examine attributes

//returns specific attribute
getAttribute("attributeName");

//returns a Map (table) of names/values
getAttributes();

Examine sub-elements

//returns a list of subelements of specified name
getElementsByTagName("subelementName");

//returns a list of all child nodes
getChildNodes();

Demo Example

以下是我们需要解析的输入 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>Vaneet</firstname>
      <lastname>Gupta</lastname>
      <nickname>vinni</nickname>
      <marks>95</marks>
   </student>

   <student rollno = "593">
      <firstname>jasvir</firstname>
      <lastname>singn</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 : Vaneet
Last Name : Gupta
Nick Name : vinni
Marks : 95

Current Element :student
Student roll no : 593
First Name : jasvir
Last Name : singn
Nick Name : jazz
Marks : 90

Java DOM Parser - Query XML Document

Demo Example

以下是我们需要查询的输入 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 :
supercarscompany : 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 :
supercarscompany : Lamborgini
car name : Lamborgini 001
car type :
car name : Lamborgini 002
car type :
car name : Lamborgini 003
car type :

Java DOM Parser - Create XML Document

Demo Example

以下是我们需要创建的 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>

Java DOM Parser - Modify XML Document

Demo Example

以下是我们需要修改的输入 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>

ModifyXmlFileDemo.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.xml");
         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>

Java SAX Parser - Overview

SAX (XML 的简单 API) 是用于 XML 文档的基于事件的解析器。与 DOM 解析器不同,SAX 解析器不会创建解析树。SAX 是用于 XML 的流式传输界面,这意味着使用 SAX 的应用程序将接收有关正在处理的 XML 文档的事件通知。这些通知包括元素和属性,它们将按从文档顶部按顺序开始,以 ROOT 元素结束的方式依次出现。

  1. 从上到下读取 XML 文档,识别构成良好形成的 XML 文档的标记。

  2. 标记按照在文档中出现的顺序进行处理。

  3. 向应用程序报告解析器在遇到标记时识别的标记性质。

  4. 应用程序提供了一个“事件”处理程序,该处理程序必须在解析器中注册。

  5. 识别标记后,将使用相关信息调用处理程序中的回调方法。

When to Use?

以下情况应使用 SAX 解析器 -

  1. 您可以从上向下线性方式处理 XML 文档。

  2. 文档没有深度嵌套。

  3. 您正在处理一个非常大的 XML 文档,其 DOM 树会消耗过多的内存。典型的 DOM 实现使用十个字节的内存来表示一个字节的 XML。

  4. 要解决的问题仅涉及 XML 文档的一部分。

  5. 数据一旦被解析器看到就可用,因此 SAX 非常适用于通过流到达的 XML 文档。

Disadvantages of SAX

  1. 由于只进行前向处理,因此我们无法随机访问 XML 文档。

  2. 如果您需要跟踪解析器已看到的数据或更改项目的顺序,则必须自己编写代码并存储数据。

ContentHandler Interface

此接口指定 SAX 解析器用于通知应用程序程序其看到的 XML 文档组件的回调方法。

  1. void startDocument() − 在文档开头调用。

  2. void endDocument() − 在文档结尾调用。

  3. void startElement(String uri, String localName, String qName, Attributes atts) − 在元素开头调用。

  4. void endElement(String uri, String localName,String qName) − 在元素结尾调用。

  5. void characters(char[] ch, int start, int length) − 在遇到字符数据时调用。

  6. void ignorableWhitespace( char[] ch, int start, int length) − 在存在 DTD 且遇到可忽略空白时调用。

  7. void processingInstruction(String target, String data) − 在识别出处理指令时调用。

  8. void setDocumentLocator(Locator locator)) − 提供一个用于标识文档中位置的定位器。

  9. void skippedEntity(String name) − 在遇到未解析的实体时调用。

  10. void startPrefixMapping(String prefix, String uri) − 在定义新的命名空间映射时调用。

  11. void endPrefixMapping(String prefix) − 在命名空间定义结束其作用域时调用。

Attributes Interface

此接口为处理连接到元素的属性指定方法。

  1. int getLength() − 返回属性数。

  2. String getQName(int index)

  3. String getValue(int index)

  4. String getValue(String qname)

Java SAX Parser - Parse XML Document

Demo Example

下面是需要解析的输入 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>Vaneet</firstname>
      <lastname>Gupta</lastname>
      <nickname>vinni</nickname>
      <marks>95</marks>
   </student>

   <student rollno = "593">
      <firstname>jasvir</firstname>
      <lastname>singn</lastname>
      <nickname>jazz</nickname>
      <marks>90</marks>
   </student>
</class>

UserHandler.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: Vaneet
Last Name: Gupta
Nick Name: vinni
Marks: 95
End Element :student
Roll No : 593
First Name: jasvir
Last Name: singn
Nick Name: jazz
Marks: 90
End Element :student

Java SAX Parser - Query XML Document

Demo Example

以下是有需要针对学号查询的输入文本文件: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>Vaneet</firstname>
      <lastname>Gupta</lastname>
      <nickname>vinni</nickname>
      <marks>95</marks>
   </student>

   <student rollno = "593">
      <firstname>jasvir</firstname>
      <lastname>singn</lastname>
      <nickname>jazz</nickname>
      <marks>90</marks>
   </student>
</class>

UserHandler.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

Java SAX Parser - Create XML Document

It is better to use StAX parser for creating XML documents rather than using SAX parser. Please refer the Java StAX Parser section for the same.

Java SAX Parser - Modify XML Document

Demo Example

以下是需要通过在 </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>Vaneet</firstname>
      <lastname>Gupta</lastname>
      <nickname>vinni</nickname>
      <marks>95</marks>
   </student>

   <student rollno = "593">
      <firstname>jasvir</firstname>
      <lastname>singn</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>
         Vaneet
      </firstname>
      <lastname>
         Gupta
      </lastname>
      <nickname>
         vinni
      </nickname>
      <marks>
         95
      </marks>
      <Result>
         Pass
      </Result>
   </student>
   <student rollno = "593">
      <firstname>
         jasvir
      </firstname>
      <lastname>
         singn
      </lastname>
      <nickname>
         jazz
      </nickname>
      <marks>
         90
      </marks>
      <Result>
         Pass
      </Result>
   </student>
</class>

Java JDOM Parser - Overview

JDOM 是一个基于 Java 的开源库,用于分析 XML 文档。它通常是一个对 Java 开发人员友好的 API。它经过 Java 优化,并且使用类似 List 和 Arrays 这样的 Java 集合。

JDOM 与 DOM 和 SAX API 配合使用,并且结合了这两个 API 的优点。它的内存占用量低,并且速度几乎与 SAX 一样快。

Environment Setup

为了使用 JDOM 解析器,您应该在应用程序的类路径中包含 jdom.jar。下载 jdom-2.0.5.zip.

When to Use?

您应在以下情况下使用 JDOM 解析器 −

  1. - 您需要了解大量有关 XML 文档结构的信息。

  2. 您需要移动 XML 文档的各个部分(例如,您可能希望对某些元素进行排序)。

  3. - 您需要多次使用 XML 文档中的信息。

  4. 您是 Java 开发人员,并且希望利用 Java 优化后的 XML 解析。

What You Get?

使用 JDOM 解析器解析 XML 文档时,灵活地可以将包含所有文档元素的树形结构返回,而无需影响应用程序的内存占用空间。

如果文档结构良好且结构已知,JDOM 会提供各种实用函数来检查 XML 文档的内容和结构。

Advantages

JDOM 为 Java 开发人员提供了 XML 解析代码的灵活性以及轻松可维护性。它是一种轻量且快速的 API。

JDOM classes

JDOM 定义了几个 Java 类。以下是常见的类:

  1. Document - 表示完整的 XML 文档。Document 对象通常被称为 DOM 树。

  2. Element - 表示一个 XML 元素。Element 对象具有操作子元素、文本、属性和名称空间的方法。

  3. Attribute - 表示一个元素的特性。特性具有的方法以获得和设置特性值。它具有父级和特性类型。

  4. Text - 表示 XML 标签的文本。

  5. Comment - 表示 XML 文档中的注释。

Common JDOM Methods

使用 JDOM 时,经常会使用多种方法 -

  1. SAXBuilder.build(xmlSource)() - 从 xml 源中构建 JDOM 文档。

  2. Document.getRootElement() - 获得 XML 的根元素。

  3. Element.getName() - 获得 XML 节点的名称。

  4. Element.getChildren() - 获得元素的所有直接子节点。

  5. Node.getChildren(Name) - 获得所有具有给定名称的直接子节点。

  6. Node.getChild(Name) - 获得具有给定名称的第一个子节点。

Java JDOM Parser - Parse XML Document

Steps to Using JDOM

以下是使用 JDOM 解析器解析文档时使用的步骤。

  1. Import XML-related packages.

  2. Create a SAXBuilder

  3. 从文件或流创建一个文档

  4. Extract the root element

  5. Examine attributes

  6. Examine sub-elements

import java.io.*;
import java.util.*;
import org.jdom2.*;

Create a DocumentBuilder

SAXBuilder saxBuilder = new SAXBuilder();

Create a Document from a file or stream

File inputFile = new File("input.txt");
SAXBuilder saxBuilder = new SAXBuilder();
Document document = saxBuilder.build(inputFile);

Extract the root element

Element classElement = document.getRootElement();

Examine attributes

//returns specific attribute
getAttribute("attributeName");

Examine sub-elements

//returns a list of subelements of specified name
getChildren("subelementName");

//returns a list of all child nodes
getChildren();

//returns first child node
getChild("subelementName");

Demo Example

下面是需要解析的输入 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>Vaneet</firstname>
      <lastname>Gupta</lastname>
      <nickname>vinni</nickname>
      <marks>95</marks>
   </student>

   <student rollno = "593">
      <firstname>jasvir</firstname>
      <lastname>singn</lastname>
      <nickname>jazz</nickname>
      <marks>90</marks>
   </student>
</class>

DomParserDemo.java

import java.io.File;
import java.io.IOException;
import java.util.List;

import org.jdom2.Attribute;
import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.JDOMException;
import org.jdom2.input.SAXBuilder;


public class JDomParserDemo {

   public static void main(String[] args) {

      try {
         File inputFile = new File("input.txt");
         SAXBuilder saxBuilder = new SAXBuilder();
         Document document = saxBuilder.build(inputFile);
         System.out.println("Root element :" + document.getRootElement().getName());
         Element classElement = document.getRootElement();

         List<Element> studentList = classElement.getChildren();
         System.out.println("----------------------------");

         for (int temp = 0; temp < studentList.size(); temp++) {
            Element student = studentList.get(temp);
            System.out.println("\nCurrent Element :"
               + student.getName());
            Attribute attribute =  student.getAttribute("rollno");
            System.out.println("Student roll no : "
               + attribute.getValue() );
            System.out.println("First Name : "
               + student.getChild("firstname").getText());
            System.out.println("Last Name : "
               + student.getChild("lastname").getText());
            System.out.println("Nick Name : "
               + student.getChild("nickname").getText());
            System.out.println("Marks : "
               + student.getChild("marks").getText());
         }
      } catch(JDOMException e) {
         e.printStackTrace();
      } catch(IOException ioe) {
         ioe.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 : Vaneet
Last Name : Gupta
Nick Name : vinni
Marks : 95

Current Element :student
Student roll no : 593
First Name : jasvir
Last Name : singn
Nick Name : jazz
Marks : 90

Java JDOM Parser - Query XML Document

Demo Example

以下是我们需要查询的输入 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

import java.io.File;
import java.io.IOException;
import java.util.List;

import org.jdom2.Attribute;
import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.JDOMException;
import org.jdom2.input.SAXBuilder;


public class QueryXmlFileDemo {

   public static void main(String[] args) {

      try {
         File inputFile = new File("input.txt");
         SAXBuilder saxBuilder = new SAXBuilder();
         Document document = saxBuilder.build(inputFile);
         System.out.println("Root element :" + document.getRootElement().getName());
         Element classElement = document.getRootElement();

         List<Element> supercarList = classElement.getChildren("supercars");
         System.out.println("----------------------------");

         for (int temp = 0; temp < supercarList.size(); temp++) {
            Element supercarElement = supercarList.get(temp);
            System.out.println("\nCurrent Element :" + supercarElement.getName());
            Attribute attribute = supercarElement.getAttribute("company");
            System.out.println("company : " + attribute.getValue() );
            List<Element> carNameList = supercarElement.getChildren("carname");

            for (int count = 0; count < carNameList.size(); count++) {
               Element carElement = carNameList.get(count);
               System.out.print("car name : ");
               System.out.println(carElement.getText());
               System.out.print("car type : ");
               Attribute typeAttribute = carElement.getAttribute("type");

               if(typeAttribute != null)
                  System.out.println(typeAttribute.getValue());
               else {
                  System.out.println("");
               }
            }
         }
      } catch(JDOMException e) {
         e.printStackTrace();
      } catch(IOException ioe) {
         ioe.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 :

Java JDOM Parser - Create XML Document

Demo Example

以下是我们要创建的 XML 文件 −

<?xml version = "1.0" encoding = "UTF-8"?>
<cars>
   <supercars company = "Ferrari">
      <carname type = "formula one">Ferrari 101</carname>
      <carname type = "sports">Ferrari 202</carname>
   </supercars>
</cars>

CreateXmlFileDemo.java

import java.io.IOException;

import org.jdom2.Attribute;
import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.output.Format;
import org.jdom2.output.XMLOutputter;


public class CreateXmlFileDemo {

   public static void main(String[] args) {

      try{
         //root element
         Element carsElement = new Element("cars");
         Document doc = new Document(carsElement);

         //supercars element
         Element supercarElement = new Element("supercars");
         supercarElement.setAttribute(new Attribute("company","Ferrari"));

         //supercars element
         Element carElement1 = new Element("carname");
         carElement1.setAttribute(new Attribute("type","formula one"));
         carElement1.setText("Ferrari 101");

         Element carElement2 = new Element("carname");
         carElement2.setAttribute(new Attribute("type","sports"));
         carElement2.setText("Ferrari 202");

         supercarElement.addContent(carElement1);
         supercarElement.addContent(carElement2);

         doc.getRootElement().addContent(supercarElement);

         XMLOutputter xmlOutput = new XMLOutputter();

         // display ml
         xmlOutput.setFormat(Format.getPrettyFormat());
         xmlOutput.output(doc, System.out);
      } catch(IOException e) {
         e.printStackTrace();
      }
   }
}

这将产生以下结果 -

<?xml version = "1.0" encoding = "UTF-8"?>
<cars>
   <supercars company = "Ferrari">
      <carname type = "formula one">Ferrari 101</carname>
      <carname type = "sports">Ferrari 202</carname>
   </supercars>
</cars>

Java JDOM Parser - Modify XML Document

Demo Example

以下是我们要修改的输入文本文件 −

<?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>

ModifyXmlFileDemo.java

import java.io.File;
import java.io.IOException;
import java.util.List;

import org.jdom2.Attribute;
import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.JDOMException;
import org.jdom2.input.SAXBuilder;
import org.jdom2.output.Format;
import org.jdom2.output.XMLOutputter;


public class ModifyXMLFileDemo {

   public static void main(String[] args) {

      try {
         File inputFile = new File("input.txt");
         SAXBuilder saxBuilder = new SAXBuilder();
         Document document = saxBuilder.build(inputFile);
         Element rootElement = document.getRootElement();

         //get first supercar
         Element supercarElement = rootElement.getChild("supercars");

         // update supercar attribute
         Attribute attribute = supercarElement.getAttribute("company");
         attribute.setValue("Lamborigini");

         // loop the supercar child node
         List<Element> list = supercarElement.getChildren();

         for (int temp = 0; temp < list.size(); temp++) {
            Element carElement = list.get(temp);

            if("Ferrari 101".equals(carElement.getText())) {
               carElement.setText("Lamborigini 001");
            }
            if("Ferrari 202".equals(carElement.getText())) {
               carElement.setText("Lamborigini 002");
            }
         }

         //get all supercars element
         List<Element> supercarslist = rootElement.getChildren();

         for (int temp = 0; temp < supercarslist.size(); temp++) {
            Element tempElement = supercarslist.get(temp);

            if("luxurycars".equals(tempElement.getName())) {
               rootElement.removeContent(tempElement);
            }
         }

         XMLOutputter xmlOutput = new XMLOutputter();

         // display xml
         xmlOutput.setFormat(Format.getPrettyFormat());
         xmlOutput.output(document, System.out);
      } catch (JDOMException e) {
         e.printStackTrace();
      } catch (IOException e) {
         e.printStackTrace();
      }
   }
}

这将产生以下结果 -

<?xml version = "1.0" encoding = "UTF-8"?>
<cars>
   <supercars company = "Lamborigini">
      <carname type = "formula one">Lamborigini 001</carname>
      <carname type = "sports">Lamborigini 002</carname>
   </supercars>
</cars>

Java StAX Parser - Overview

StAX 是一个基于 Java 的 API,用于解析 XML 文档,与 SAX 解析器类似。但这两个 API 存在两个主要差异 −

  1. StAX 是一个 PULL API,而 SAX 是一个 PUSH API。这意味着对于 StAX 解析器,当它需要时,客户端应用程序需要请求 StAX 解析器从 XML 获取信息。但在使用 SAX 解析器时,客户端应用程序需要在 SAX 解析器通知客户端应用程序信息可用时获取信息。

  2. StAX API 可以读取和写入 XML 文档。使用 SAX API,只能读取 XML 文件。

Environment Setup

若要使用 StAX 解析器,应该在应用程序的类路径中包含 stax.jar。

以下是 StAX API 的特性:

  1. 从上到下读取 XML 文档,识别构成良好形成的 XML 文档的标记。

  2. 标记按照在文档中出现的顺序进行处理。

  3. 向应用程序报告解析器在遇到标记时识别的标记性质。

  4. 应用程序提供了一个“事件”读取器,该读取器充当迭代器并在事件上迭代以获取所需信息。另一个可用的读取器是“游标”,它充当指向 XML 节点的指针。

  5. 随着事件被识别出来,可以从事件对象中检索 XML 元素并对其进行进一步处理。

When to Use?

您应该在以下情况下使用 StAX 解析器:

  1. 您可以从上向下线性方式处理 XML 文档。

  2. 文档没有深度嵌套。

  3. 您正在处理一个非常大的 XML 文档,其 DOM 树会消耗过多的内存。典型的 DOM 实现使用十个字节的内存来表示一个字节的 XML。

  4. 要解决的问题仅涉及 XML 文档的一部分。

  5. 解析器一看到数据便立即能用,因此 StAX 非常适用于流式传输的 XML 文档。

Disadvantages of SAX

  1. 由于以仅正向的方式处理 XML 文档,因此,我们无法随机访问 XML 文档。

  2. 如果您需要跟踪解析器已看到的数据或者解析器已更改项的顺序,则必须编写代码并自行存储数据。

XMLEventReader Class

此类提供事件迭代器,该迭代器可在解析 XML 文档时用来迭代事件。

  1. StartElement asStartElement() − 用于检索元素的值和属性。

  2. EndElement asEndElement() − 在元素结尾处调用。

  3. Characters asCharacters() − 可用于获取字符,如 CDATA、空白等。

XMLEventWriter Class

此接口指定用于创建事件的方法。

  1. add(Event event) − 向 XML 添加包含元素的事件。

XMLStreamReader Class

此类提供事件迭代器,该迭代器可在解析 XML 文档时用来迭代事件。

  1. int next() − 用于检索下一个事件。

  2. boolean hasNext() − 用于检查是否存在进一步的事件。

  3. String getText() − 用于获取元素的文本。

  4. String getLocalName() − 用于获取元素的名称。

XMLStreamWriter Class

此接口指定用于创建事件的方法。

  1. writeStartElement(String localName) − 添加已给定名称的开始元素。

  2. writeEndElement(String localName) − 添加已给定名称的结束元素。

  3. writeAttribute(String localName, String value) − 向元素写入属性。

Java StAX Parser - Parse XML Document

Demo Example

以下是我们需要解析的输入 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>Vaneet</firstname>
      <lastname>Gupta</lastname>
      <nickname>vinni</nickname>
      <marks>95</marks>
   </student>

   <student rollno = "593">
      <firstname>jasvir</firstname>
      <lastname>singn</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: Vaneet
Last Name: Gupta
Nick Name: vinni
Marks: 95
End Element : student

Start Element : student
Roll No : 593
First Name: jasvir
Last Name: singn
Nick Name: jazz
Marks: 90
End Element : student

Java StAX Parser - Query XML Document

Demo Example

以下是我们需要解析的输入 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>Vaneet</firstname>
      <lastname>Gupta</lastname>
      <nickname>vinni</nickname>
      <marks>95</marks>
   </student>

   <student rollno = "593">
      <firstname>jasvir</firstname>
      <lastname>singn</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.asEndElement();

               if(endElement.getName().getLocalPart().equalsIgnoreCase(
                  "student") && isRequestRollNo) {
                  System.out.println("End Element : student");
                  System.out.println();
                  isRequestRollNo = false;
               }
               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

Java StAX Parser - Create XML Document

Demo Example

以下是我们需要创建的 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>

StAXCreateXMLDemo.java

package com.tutorialspoint.xml;

import java.io.IOException;
import java.io.StringWriter;

import javax.xml.stream.XMLOutputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamWriter;

public class StAXCreateXMLDemo {

   public static void main(String[] args) {

      try {
         StringWriter stringWriter = new StringWriter();

         XMLOutputFactory xMLOutputFactory = XMLOutputFactory.newInstance();
         XMLStreamWriter xMLStreamWriter =
            xMLOutputFactory.createXMLStreamWriter(stringWriter);

         xMLStreamWriter.writeStartDocument();
         xMLStreamWriter.writeStartElement("cars");

         xMLStreamWriter.writeStartElement("supercars");
         xMLStreamWriter.writeAttribute("company", "Ferrari");

         xMLStreamWriter.writeStartElement("carname");
         xMLStreamWriter.writeAttribute("type", "formula one");
         xMLStreamWriter.writeCharacters("Ferrari 101");
         xMLStreamWriter.writeEndElement();

         xMLStreamWriter.writeStartElement("carname");
         xMLStreamWriter.writeAttribute("type", "sports");
         xMLStreamWriter.writeCharacters("Ferrari 202");
         xMLStreamWriter.writeEndElement();

         xMLStreamWriter.writeEndElement();
         xMLStreamWriter.writeEndDocument();

         xMLStreamWriter.flush();
         xMLStreamWriter.close();

         String xmlString = stringWriter.getBuffer().toString();

         stringWriter.close();

         System.out.println(xmlString);

      } catch (XMLStreamException e) {
         e.printStackTrace();
      } catch (IOException e) {
         // TODO Auto-generated catch block
         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>

Java StAX Parser - Modify XML Document

Demo Example

以下是我们需要修改的 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>Vaneet</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>

StAXModifyDemo.java

package com.tutorialspoint.xml;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.Iterator;
import java.util.List;

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.StartElement;
import javax.xml.stream.events.XMLEvent;

import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.JDOMException;
import org.jdom2.input.SAXBuilder;
import org.jdom2.output.Format;
import org.jdom2.output.XMLOutputter;

public class StAXModifyDemo {

   public static void main(String[] args) {

      try {
         XMLInputFactory factory = XMLInputFactory.newInstance();
         XMLEventReader eventReader = factory.createXMLEventReader(
            new FileReader("input.txt"));
         SAXBuilder saxBuilder = new SAXBuilder();
         Document document = saxBuilder.build(new File("input.txt"));
         Element rootElement = document.getRootElement();
         List<Element> studentElements = rootElement.getChildren("student");

         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("393")) {
                     //get the student with roll no 393

                     for(int i = 0;i < studentElements.size();i++) {
                        Element studentElement = studentElements.get(i);

                        if(studentElement.getAttribute(
                           "rollno").getValue().equalsIgnoreCase("393")) {
                           studentElement.removeChild("marks");
                           studentElement.addContent(new Element("marks").setText("80"));
                        }
                     }
                  }
               }
               break;
            }
         }
         XMLOutputter xmlOutput = new XMLOutputter();

         // display xml
         xmlOutput.setFormat(Format.getPrettyFormat());
         xmlOutput.output(document, System.out);
      } catch (FileNotFoundException e) {
         e.printStackTrace();
      } catch (XMLStreamException e) {
         e.printStackTrace();
      } catch (JDOMException e) {
         e.printStackTrace();
      } catch (IOException e) {
         e.printStackTrace();
      }
   }
}

这将产生以下结果 -

<?xml version = "1.0" encoding = "UTF-8"?>
<student rollno = "393">
   <firstname>dinkar</firstname>
   <lastname>kad</lastname>
   <nickname>dinkar</nickname>
   <marks>80</marks>
</student>
<student rollno = "493">
   <firstname>Vaneet</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>

Java XPath Parser - Overview

XPath 是万维网联盟 (W3C) 的官方推荐。它定义了一种在 XML 文件中查找信息的语言。它用于遍历 XML 文档的元素和属性。XPath 提供了多种类型的表达式,可用于从 XML 文档中查询相关信息。

What is XPath?

  1. Structure Definations − XPath 定义 XML 文档的各个部分,如元素、属性、文本、命名空间、处理指令、注释和文档节点。

  2. Path Expressions - XPath 提供了功能强大的路径表达式,例如选择 XML 文档中的节点或节点列表。

  3. Standard Functions - XPath 提供了一个丰富的标准函数库,可用于处理字符串值、数值值、日期和时间比较、节点和 QName 处理、序列处理、布尔值等。

  4. Major part of XSLT − XPath 是 XSLT 标准中的主要元素之一,必须充分了解 XPath 才能使用 XSLT 文档。

  5. W3C recommendation - XPath 是万维网联盟 (W3C) 的官方推荐。

XPath Expressions

XPath 使用路径表达式从 XML 文档中选择节点或节点列表。下面列出了有用的路径和表达式,用于从 XML 文档中选择任何节点/节点列表。

Sr.No.

Expression & Description

1

node-name 选择具有指定名称 “nodename” 的所有节点

2

/ 从根节点开始选择

3

// 从符合选择的当前节点开始选择

4

. Selects the current node

5

.. 选择当前节点的父级

6

@ Selects attributes

7

student Example - 选择名称为 “student” 的所有节点

8

class/student Example - 选择所有作为 class 子代的 student 元素

9

无论在文档中的什么位置,选择所有 student 元素

Predicates

谓词用于查找特定节点或包含特定值的节点,并使用 […​] 定义。

Expression

Result

/class/student[1]

选择 class 元素的子元素中的第一个 student 元素。

/class/student[last()]

选择 class 元素的子元素中的最后一个 student 元素。

/class/student[last()-1]

选择 class 元素子元素中倒数第二个的学生元素。

//student[@rollno = '493']

选择所有具有名为rollno的属性且值等于'493’的学生元素。

Java XPath Parser - Parse XML Document

Steps to Using XPath

使用 XPath 分析器解析文档时,以下步骤将被用作。

  1. Import XML-related packages.

  2. Create a DocumentBuilder.

  3. 从文件或流中创建 Document。

  4. 创建一个 Xpath 对象和一个 XPath 路径表达式。

  5. 使用 XPath.compile() 编译 XPath 表达式,并通过 XPath.evaluate() 评估编译的表达式来获取节点列表。

  6. 遍历节点列表。

  7. Examine attributes.

  8. Examine sub-elements.

import org.w3c.dom.*;
import org.xml.sax.*;
import javax.xml.parsers.*;
import javax.xml.xpath.*;
import java.io.*;

Create a DocumentBuilder

DocumentBuilderFactory factory =
DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();

Create a Document from a file or stream

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);

Build XPath

XPath xPath =  XPathFactory.newInstance().newXPath();

Prepare Path expression and evaluate it

String expression = "/class/student";
NodeList nodeList = (NodeList) xPath.compile(expression).evaluate(
   doc, XPathConstants.NODESET);

Iterate over NodeList

for (int i = 0; i < nodeList.getLength(); i++) {
   Node nNode = nodeList.item(i);
   ...
}

Examine attributes

//returns specific attribute
getAttribute("attributeName");

//returns a Map (table) of names/values
getAttributes();

Examine sub-elements

//returns a list of subelements of specified name
getElementsByTagName("subelementName");

//returns a list of all child nodes
getChildNodes();

Demo Example

以下是我们需要解析的输入文本文件 -

<?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>Vaneet</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>

XPathParserDemo.java

package com.tutorialspoint.xml;

import java.io.File;
import java.io.IOException;

import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;

import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import org.w3c.dom.Node;
import org.w3c.dom.Element;
import org.xml.sax.SAXException;

public class XPathParserDemo {

   public static void main(String[] args) {

      try {
         File inputFile = new File("input.txt");
         DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
         DocumentBuilder dBuilder;

         dBuilder = dbFactory.newDocumentBuilder();

         Document doc = dBuilder.parse(inputFile);
         doc.getDocumentElement().normalize();

         XPath xPath =  XPathFactory.newInstance().newXPath();

         String expression = "/class/student";
         NodeList nodeList = (NodeList) xPath.compile(expression).evaluate(
            doc, XPathConstants.NODESET);

         for (int i = 0; i < nodeList.getLength(); i++) {
            Node nNode = nodeList.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("Nick Name : "
                  + eElement
                  .getElementsByTagName("nickname")
                  .item(0)
                  .getTextContent());
               System.out.println("Marks : "
                  + eElement
                  .getElementsByTagName("marks")
                  .item(0)
                  .getTextContent());
            }
         }
      } catch (ParserConfigurationException e) {
         e.printStackTrace();
      } catch (SAXException e) {
         e.printStackTrace();
      } catch (IOException e) {
         e.printStackTrace();
      } catch (XPathExpressionException e) {
         e.printStackTrace();
      }
   }
}

这将产生以下结果 -

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 : Vaneet
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

Java XPath Parser - Query XML Document

Demo Example

以下是我们需要查询的输入文本文件 -

<?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>Vaneet</firstname>
      <lastname>Gupta</lastname>
      <nickname>vinni</nickname>
      <marks>95</marks>
   </student>

   <student rollno = "593">
      <firstname>jasvir</firstname>
      <lastname>singn</lastname>
      <nickname>jazz</nickname>
      <marks>90</marks>
   </student>
</class>

XPathParserDemo.java

package com.tutorialspoint.xml;

import java.io.File;
import java.io.IOException;

import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;

import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import org.w3c.dom.Node;
import org.w3c.dom.Element;
import org.xml.sax.SAXException;

public class XPathParserDemo {

   public static void main(String[] args) {

      try {
         File inputFile = new File("input.txt");
         DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
         DocumentBuilder dBuilder;

         dBuilder = dbFactory.newDocumentBuilder();

         Document doc = dBuilder.parse(inputFile);
         doc.getDocumentElement().normalize();

         XPath xPath =  XPathFactory.newInstance().newXPath();

         String expression = "/class/student[@rollno = '493']";
         NodeList nodeList = (NodeList) xPath.compile(expression).evaluate(
            doc, XPathConstants.NODESET);

         for (int i = 0; i < nodeList.getLength(); i++) {
            Node nNode = nodeList.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("Nick Name : "
                  + eElement
                  .getElementsByTagName("nickname")
                  .item(0)
                  .getTextContent());
               System.out.println("Marks : "
                  + eElement
                  .getElementsByTagName("marks")
                  .item(0)
                  .getTextContent());
            }
         }
      } catch (ParserConfigurationException e) {
         e.printStackTrace();
      } catch (SAXException e) {
         e.printStackTrace();
      } catch (IOException e) {
         e.printStackTrace();
      } catch (XPathExpressionException e) {
         e.printStackTrace();
      }
   }
}

这将产生以下结果 -

Current Element :student
Student roll no : 493
First Name : Vaneet
Last Name : Gupta
Nick Name : vinni
Marks : 95

Java XPath Parser - Create XML Document

XPath parser is used to navigate XML Documents only. It is better to use DOM parser for creating XML. Please refer the Java DOM Parser section for the same.

Java XPath Parser - Modify XML Document

XPath parser is used to navigate XML Documents only. It is better to use DOM parser for modifying XML. Please refer the Java DOM Parser section for the same.

Java DOM4J Parser - Overview

DOM4J 是一个基于 Java 的开源库,用于解析 XML 文档。它是一个高度灵活且内存高效的 API。它经过 Java 优化,并使用 Java 集合,如 List 和 Arrays。

DOM4J 与 DOM、SAX、XPath 和 XSLT 配合使用。它可以用非常小的内存占用解析大型 XML 文档。

Environment Setup

为了使用 DOM4J 分析器,您应在您的应用程序的类路径中包含 dom4j-1.6.1.jar 和 jaxen.jar。下载 dom4j-1.6.1.zip.

When to Use?

以下情况时,您应使用 DOM4J 解析器:

  1. - 您需要了解大量有关 XML 文档结构的信息。

  2. - 您需要移动 XML 文档的各个部分(例如,您可能需要对某些元素进行排序)。

  3. - 您需要多次使用 XML 文档中的信息。

  4. - 您是 Java 开发人员,希望利用经过 Java 优化的 XML 解析。

What You Get?

当您使用 DOM4J 解析器解析 XML 文档时,您可以灵活地获取包含文档所有元素的树结构,而不会影响应用程序的内存占用。

如果文档结构良好且结构已知,DOM4J 提供了多种实用工具函数,供您检查 XML 文档的内容和结构。

DOM4J 使用 XPath 表达式来浏览 XML 文档。

Advantages

DOM4J 为 Java 开发人员提供了 XML 解析代码的灵活性和易维护性。这是一个轻量且快速的 API。

DOM4J Classes

DOM4J 定义了多个 Java 类。以下是其中最常见的类 −

  1. Document − 表示整个 XML 文档。文档对象通常称为 DOM 树。

  2. Element − 表示一个 XML 元素。Element 对象有用于操作其子元素、文本、属性和名称空间的方法。

  3. Attribute - 表示一个元素的特性。特性具有的方法以获得和设置特性值。它具有父级和特性类型。

  4. Node − 表示 Element、Attribute 或 ProcessingInstruction。

Common DOM4J methods

在使用 DOM4J 时,您将经常使用以下几种方法 −

  1. SAXReader.read(xmlSource)() − 从 XML 来源构建 DOM4J 文档。

  2. Document.getRootElement() − 获取 XML 文档的根元素。

  3. Element.node(index) − 获取元素中特定索引处的 XML 节点。

  4. Element.attributes() − 获取元素的所有属性。

  5. Node.valueOf(@Name) − 获取具有元素给定名称的属性的值。

Java DOM4J Parser - Parse XML Document

Steps to Using DOM4J

以下是使用 DOM4J 解析器解析文档时的步骤。

  1. Import XML-related packages.

  2. Create a SAXReader.

  3. 从文件或流中创建 Document。

  4. 通过调用 document.selectNodes() 使用 XPath 表达式获取所需节点

  5. Extract the root element.

  6. 遍历节点列表。

  7. Examine attributes.

  8. Examine sub-elements.

import java.io.*;
import java.util.*;
import org.dom4j.*;

Create a DocumentBuilder

SAXBuilder saxBuilder = new SAXBuilder();

Create a Document from a file or stream

File inputFile = new File("input.txt");
SAXBuilder saxBuilder = new SAXBuilder();
Document document = saxBuilder.build(inputFile);

Extract the root element

Element classElement = document.getRootElement();

Examine attributes

//returns specific attribute
valueOf("@attributeName");

Examine sub-elements

//returns first child node
selectSingleNode("subelementName");

Demo Example

以下是我们需要解析的输入 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>Vaneet</firstname>
      <lastname>Gupta</lastname>
      <nickname>vinni</nickname>
      <marks>95</marks>
   </student>

   <student rollno = "593">
      <firstname>jasvir</firstname>
      <lastname>singn</lastname>
      <nickname>jazz</nickname>
      <marks>90</marks>
   </student>
</class>

DOM4JParserDemo.java

package com.tutorialspoint.xml;

import java.io.File;
import java.util.List;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.Node;
import org.dom4j.io.SAXReader;

public class DOM4JParserDemo {

   public static void main(String[] args) {

      try {
         File inputFile = new File("input.txt");
         SAXReader reader = new SAXReader();
         Document document = reader.read( inputFile );

         System.out.println("Root element :" + document.getRootElement().getName());

         Element classElement = document.getRootElement();

         List<Node> nodes = document.selectNodes("/class/student" );
         System.out.println("----------------------------");

         for (Node node : nodes) {
            System.out.println("\nCurrent Element :"
               + node.getName());
            System.out.println("Student roll no : "
               + node.valueOf("@rollno") );
            System.out.println("First Name : "
               + node.selectSingleNode("firstname").getText());
            System.out.println("Last Name : "
               + node.selectSingleNode("lastname").getText());
            System.out.println("First Name : "
               + node.selectSingleNode("nickname").getText());
            System.out.println("Marks : "
               + node.selectSingleNode("marks").getText());
         }
      } catch (DocumentException e) {
         e.printStackTrace();
      }
   }
}

这将产生以下结果 -

Root element :class
----------------------------

Current Element :student
Student roll no :
First Name : dinkar
Last Name : kad
First Name : dinkar
Marks : 85

Current Element :student
Student roll no :
First Name : Vaneet
Last Name : Gupta
First Name : vinni
Marks : 95

Current Element :student
Student roll no :
First Name : jasvir
Last Name : singn
First Name : jazz
Marks : 90

Java DOM4J Parser - Query XML Document

Demo Example

以下是我们需要解析的输入 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>Vaneet</firstname>
      <lastname>Gupta</lastname>
      <nickname>vinni</nickname>
      <marks>95</marks>
   </student>

   <student rollno = "593">
      <firstname>jasvir</firstname>
      <lastname>singn</lastname>
      <nickname>jazz</nickname>
      <marks>90</marks>
   </student>
</class>

DOM4JQueryDemo.java

package com.tutorialspoint.xml;

import java.io.File;
import java.util.List;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.Node;
import org.dom4j.io.SAXReader;

public class DOM4JQueryDemo {

   public static void main(String[] args) {

      try {
         File inputFile = new File("input.txt");
         SAXReader reader = new SAXReader();
         Document document = reader.read( inputFile );

         System.out.println("Root element :" + document.getRootElement().getName());

         Element classElement = document.getRootElement();

         List<Node> nodes = document.selectNodes("/class/student[@rollno = '493']" );
         System.out.println("----------------------------");

         for (Node node : nodes) {
            System.out.println("\nCurrent Element :"
               + node.getName());
            System.out.println("Student roll no : "
               + node.valueOf("@rollno") );
            System.out.println("First Name : "
               + node.selectSingleNode("firstname").getText());
            System.out.println("Last Name : "
               + node.selectSingleNode("lastname").getText());
            System.out.println("First Name : "
               + node.selectSingleNode("nickname").getText());
            System.out.println("Marks : "
               + node.selectSingleNode("marks").getText());
         }
      } catch (DocumentException e) {
         e.printStackTrace();
      }
   }
}

这将产生以下结果 -

Root element :class
----------------------------
Current Element :student
Student roll no : 493
First Name : Vaneet
Last Name : Gupta
First Name : vinni
Marks : 95

Java DOM4J Parser - Create XML Document

Demo Example

以下是我们需要创建的 XML −

<?xml version = "1.0" encoding = "UTF-8"?>
<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 java.io.IOException;
import java.io.UnsupportedEncodingException;

import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.XMLWriter;

public class DOM4JCreateXMLDemo {

   public static void main(String[] args) {

      try {
         Document document = DocumentHelper.createDocument();
         Element root = document.addElement( "cars" );
         Element supercarElement = root.addElement("supercars")
            .addAttribute("company", "Ferrai");

         supercarElement.addElement("carname")
            .addAttribute("type", "Ferrari 101")
            .addText("Ferrari 101");

         supercarElement.addElement("carname")
            .addAttribute("type", "sports")
            .addText("Ferrari 202");

         // Pretty print the document to System.out
         OutputFormat format = OutputFormat.createPrettyPrint();
         XMLWriter writer;
         writer = new XMLWriter( System.out, format );
         writer.write( document );
      } catch (UnsupportedEncodingException e) {
         e.printStackTrace();
      } catch (IOException e) {
         e.printStackTrace();
      }
   }
}

这将产生以下结果 -

<?xml version = "1.0" encoding = "UTF-8"?>
<cars>
   <supercars company = "Ferrari">
      <carname type = "formula one">Ferrari 101</carname>
      <carname type = "sports">Ferrari 202</carname>
   </supercars>
</cars>

Java DOM4J Parser - Modify XML Document

Demo Example

以下是我们需要修改的 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>Vaneet</firstname>
      <lastname>Gupta</lastname>
      <nickname>vinni</nickname>
      <marks>95</marks>
   </student>

   <student rollno = "593">
      <firstname>jasvir</firstname>
      <lastname>singn</lastname>
      <nickname>jazz</nickname>
      <marks>90</marks>
   </student>
</class>

DOM4jModifyXMLDemo.java

package com.tutorialspoint.xml;

import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.Iterator;
import java.util.List;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.Node;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;

public class DOM4jModifyXMLDemo {

   public static void main(String[] args) {

      try {
         File inputFile = new File("input.txt");
         SAXReader reader = new SAXReader();
         Document document = reader.read( inputFile );

         Element classElement = document.getRootElement();

         List<Node> nodes = document.selectNodes("/class/student[@rollno = '493']" );

         for (Node node : nodes) {
            Element element = (Element)node;
            Iterator<Element> iterator = element.elementIterator("marks");

            while(iterator.hasNext()) {
               Element marksElement = (Element)iterator.next();
               marksElement.setText("80");
            }
         }

         // Pretty print the document to System.out
         OutputFormat format = OutputFormat.createPrettyPrint();
         XMLWriter writer;
         writer = new XMLWriter( System.out, format );
         writer.write( document );
      } catch (DocumentException e) {
         e.printStackTrace();
      } catch (UnsupportedEncodingException e) {
         e.printStackTrace();
      } catch (IOException e) {
         e.printStackTrace();
      }
   }
}

这将产生以下结果 -

<?xml version = "1.0" encoding = "UTF-8"?>

<class>
   <student rollno = "393">
      <firstname>dinkar</firstname>
      <lastname>kad</lastname>
      <nickname>dinkar</nickname>
      <marks>85</marks>
   </student>
   <student rollno = "493">
      <firstname>Vaneet</firstname>
      <lastname>Gupta</lastname>
      <nickname>vinni</nickname>
      <marks>80</marks>
   </student>
   <student rollno = "593">
      <firstname>jasvir</firstname>
      <lastname>singn</lastname>
      <nickname>jazz</nickname>
      <marks>90</marks>
   </student>
</class>