目录

Java XML - 快速指南

Java XML - Overview

什么是XML?

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

  • XML是一种标记语言。

  • XML是一种基于标签的语言,如HTML。

  • XML标记不像HTML那样预定义。

  • 您可以定义自己的标记,这就是它被称为可扩展语言的原因。

  • XML标记旨在自我描述。

  • 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提供的优势 -

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

  • Human readable - XML使用简单的文本格式。 它是人类可读和可理解的。

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

  • Allow Validation - 可以轻松Allow Validation使用XSD,DTD和XML结构。

缺点 (Disadvantages)

以下是使用XML的缺点 -

  • Redundant Syntax - 通常XML文件包含许多重复的术语。

  • Verbose - XML文件大小是一种冗长的语言,会增加传输和存储成本。

Java XML - Parsers

XML解析是指通过XML文档来访问或修改数据。

什么是XML Parser?

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

  • Dom Parser - 通过加载文档的完整内容并在内存中创建完整的分层树来解析XML文档。

  • SAX Parser - 解析基于事件的触发器的XML文档。 不将完整文档加载到内存中。

  • JDOM Parser - 以与DOM解析器类似的方式解析XML文档,但更简单。

  • StAX Parser - 以类似于SAX解析器的方式解析XML文档,但是以更有效的方式解析。

  • XPath Parser - 基于表达式解析XML文档,并与XSLT一起广泛使用。

  • 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解析器 -

  • 您需要了解很多关于文档结构的知识。

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

  • 您需要多次使用XML文档中的信息。

你得到什么?

使用DOM解析器解析XML文档时,将返回包含文档所有元素的树结构。 DOM提供了各种可用于检查文档内容和结构的函数。

优势 (Advantages)

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

DOM接口

DOM定义了几个Java接口。 以下是最常见的界面 -

  • Node - DOM的基本数据类型。

  • Element - 您将要处理的绝大多数对象都是元素。

  • Attr - 表示元素的属性。

  • Text - Element或Attr的实际内容。

  • Document - 表示整个XML文档。 Document对象通常称为DOM树。

常见的DOM方法

当您使用DOM时,您经常会使用几种方法 -

  • Document.getDocumentElement() - 返回Document.getDocumentElement()的根元素。

  • Node.getFirstChild() - 返回给定节点的第一个子节点。

  • Node.getLastChild() - 返回给定节点的最后一个子节点。

  • Node.getNextSibling() - 这些方法返回给定节点的下一个兄弟节点。

  • Node.getPreviousSibling() - 这些方法返回给定Node的前一个兄弟节点。

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

Java DOM Parser - Parse XML Document

使用JDOM的步骤

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

  • 导入与XML相关的包。
  • 创建一个DocumentBuilder
  • 从文件或流创建文档
  • 提取根元素
  • 检查属性
  • 检查子元素

Import XML-related packages

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

创建一个DocumentBuilder (Create a DocumentBuilder)

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

检查属性 (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.iowiki.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.iowiki.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.iowiki.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.iowiki.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(Simple API for XML)是一种基于事件的XML文档解析器。 与DOM解析器不同,SAX解析器不会创建解析树。 SAX是XML的流式接口,这意味着使用SAX的应用程序接收有关正在处理的XML文档的事件通知元素和属性,从文档顶部开始按顺序排列,然后关闭ROOT元素。

  • 从上到下读取XML文档,识别构成格式良好的XML文档的标记。

  • 令牌的处理顺序与它们在文档中出现的顺序相同。

  • 向应用程序报告解析器在发生时遇到的令牌的性质。

  • 应用程序提供必须向解析器注册的“事件”处理程序。

  • 在标识令牌时,将使用相关信息调用处理程序中的回调方法。

什么时候使用? (When to Use?)

你应该使用SAX解析器 -

  • 您可以从上到下以线性方式处理XML文档。

  • 该文档没有深层嵌套。

  • 您正在处理一个非常大的XML文档,其DOM树将消耗太多内存。 典型的DOM实现使用10个字节的内存来表示XML的一个字节。

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

  • 解析器一看到数据就会立即可用,因此SAX适用于通过流到达的XML文档。

SAX的缺点

  • 我们没有随机访问XML文档,因为它是以仅向前的方式处理的。

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

ContentHandler接口

此接口指定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 characters(char[] ch, int start, int length) - 遇到字符数据时调用。

  • void ignorableWhitespace( char[] ch, int start, int length) - 当存在DTD并且遇到可忽略的空格时调用。

  • void processingInstruction(String target, String data) - 在识别处理指令时调用。

  • void setDocumentLocator(Locator locator)) - 提供可用于标识文档中位置的Locator。

  • void skippedEntity(String name) - 遇到未解析的实体时调用。

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

  • void endPrefixMapping(String prefix) - 在命名空间定义结束其范围时调用。

属性接口

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

  • int getLength() - 返回属性数。

  • String getQName(int index)

  • String getValue(int index)

  • 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.iowiki.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.iowiki.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)

这是我们需要查询rollno的输入文本文件: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.iowiki.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.iowiki.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>标记的末尾附加 Pass 来修改的输入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.iowiki.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,并结合了两者中的最佳功能。 它的内存占用率低,几乎与SAX一样快。

环境设置 (Environment Setup)

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

什么时候使用? (When to Use?)

你应该使用JDOM解析器 -

  • 您需要了解很多关于XML文档结构的知识。

  • 您需要移动XMl文档的一部分(例如,您可能希望对某些元素进行排序)。

  • 您需要多次使用XML文档中的信息。

  • 您是Java开发人员,希望利用Java优化的XML解析。

你得到什么?

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

JDOM提供了各种实用程序函数,您可以使用它们来检查XML文档的内容和结构,以防文档结构良好且结构已知。

优势 (Advantages)

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

JDOM类

JDOM定义了几个Java类。 以下是最常见的课程 -

  • Document - 表示整个XML文档。 Document对象通常称为DOM树。

  • Element - 表示XML元素。 Element对象具有操作其子元素,其文本,属性和命名空间的方法。

  • Attribute - 表示元素的属性。 Attribute具有获取和设置属性值的方法。 它具有父类和属性类型。

  • Text - 表示XML标记的文本。

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

常见的JDOM方法

当您使用JDOM时,您经常会使用几种方法 -

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

  • Document.getRootElement() - 获取XML的根元素。

  • Element.getName() - 获取XML节点的名称。

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

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

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

Java JDOM Parser - Parse XML Document

使用JDOM的步骤

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

  • 导入与XML相关的包。
  • 创建一个SAXBuilder
  • 从文件或流创建文档
  • 提取根元素
  • 检查属性
  • 检查子元素

Import XML-related packages

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

创建一个DocumentBuilder (Create a DocumentBuilder)

SAXBuilder saxBuilder = new SAXBuilder();

从文件或流创建文档

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

提取根元素

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,用于以与SAX解析器类似的方式解析XML文档。 但这两个API有两个主要区别 -

  • StAX是一个PULL API,而SAX是一个PUSH API。 这意味着在StAX解析器的情况下,客户端应用程序需要要求StAX解析器在需要时从XML获取信息。 但是在SAX解析器的情况下,当SAX解析器通知客户端应用程序信息可用时,需要客户端应用程序来获取信息。

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

环境设置 (Environment Setup)

为了使用StAX解析器,您应该在应用程序的类路径中使用stax.jar。

以下是StAX API的功能 -

  • 从上到下读取XML文档,识别构成格式良好的XML文档的标记。

  • 令牌的处理顺序与它们在文档中出现的顺序相同。

  • 向应用程序报告解析器在发生时遇到的令牌的性质。

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

  • 在识别事件时,可以从事件对象中检索XML元素,并可以进一步处理。

什么时候使用? (When to Use?)

你应该使用StAX解析器 -

  • 您可以从上到下以线性方式处理XML文档。

  • 该文档没有深层嵌套。

  • 您正在处理一个非常大的XML文档,其DOM树将消耗太多内存。 典型的DOM实现使用10个字节的内存来表示XML的一个字节。

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

  • 解析器一看到数据就会立即可用,因此StAX适用于通过流到达的XML文档。

SAX的缺点

  • 我们没有随机访问XML文档,因为它是以只进的方式处理的。

  • 如果您需要跟踪解析器已经看到的数据或解析器更改项目顺序的位置,那么您必须编写代码并将数据存储在您自己的位置。

XMLEventReader类

此类提供事件的迭代器,可用于在解析XML文档时对事件进行迭代。

  • StartElement asStartElement() - 用于检索元素的值和属性。

  • EndElement asEndElement() - 在元素的末尾调用。

  • Characters asCharacters() - 可用于获取CDATA,空格等字符。

XMLEventWriter类

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

  • add(Event event) - 将包含元素的add(Event event)添加到XML。

XMLStreamReader类

此类提供事件的迭代器,可用于在解析XML文档时对事件进行迭代。

  • int next() - 用于检索下一个事件。

  • boolean hasNext() - 用于检查是否存在其他事件。

  • String getText() - 用于获取元素的文本。

  • String getLocalName() - 用于获取元素的名称。

XMLStreamWriter类

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

  • writeStartElement(String localName) - 添加给定名称的start元素。

  • writeEndElement(String localName) - 添加给定名称的结束元素。

  • 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.iowiki.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.iowiki.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.iowiki.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.iowiki.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文档中查询相关信息。

什么是XPath?

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

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

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

  • Major part of XSLT - XPath是XSLT标准中的主要元素之一,并且必须具备足够的XPath知识才能使用XSLT文档。

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

XPath表达式

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

Sr.No. 表达和描述
1

node-name

选择具有给定名称“nodename”的所有节点

2

/

选择从根节点开始

3

//

选择从与选择匹配的当前节点开始

4

.

选择当前节点

5

..

选择当前节点的父节点

6

@

选择属性

7

student

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

8

class/student

Example - 选择作为类的子项的所有学生元素

9

//student

选择所有学生元素,无论他们在文档中的位置

谓词(Predicates)

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

表达 结果
/class/student[1] 选择第一个学生元素,该元素是class元素的子元素。
/class/student[last()] 选择作为class元素的子元素的最后一个student元素。
/class/student[last()-1] 选择作为class元素的子元素的最后一个student元素。
//student[@rollno = '493'] 选择具有名为rollno的属性且值为“493”的所有学生元素

Java XPath Parser - Parse XML Document

使用XPath的步骤

以下是使用XPath Parser解析文档时使用的步骤。

  • 导入与XML相关的包。

  • 创建一个DocumentBuilder。

  • 从文件或流创建文档。

  • 创建Xpath对象和XPath路径表达式。

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

  • 迭代节点列表。

  • 检查属性。

  • 检查子元素。

Import XML-related packages

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

创建一个DocumentBuilder (Create a DocumentBuilder)

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

构建XPath

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

准备路径表达式并对其进行评估

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

迭代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.iowiki.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.iowiki.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优化的,使用像List和Arrays这样的Java集合。

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解析器 -

  • 您需要了解很多关于XML文档结构的知识。

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

  • 您需要多次使用XML文档中的信息。

  • 您是Java开发人员,希望利用Java优化的XML解析。

你得到什么?

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

DOM4J提供了各种实用程序函数,您可以使用这些函数来检查XML文档的内容和结构,以防文档结构良好且结构已知。

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

优势 (Advantages)

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

DOM4J类

DOM4J定义了几个Java类。 以下是最常见的课程 -

  • Document - 表示整个XML文档。 Document对象通常称为DOM树。

  • Element - 表示XML元素。 Element对象具有操作其子元素,文本,属性和命名空间的方法。

  • Attribute - 表示元素的属性。 Attribute具有获取和设置属性值的方法。 它具有父类和属性类型。

  • Node - 表示元素,属性或ProcessingInstruction。

常见的DOM4J方法

当你使用DOM4J时,你会经常使用几种方法 -

  • SAXReader.read(xmlSource)() - 从XML源构建DOM4J文档。

  • Document.getRootElement() - 获取XML文档的根元素。

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

  • Element.attributes() - 获取元素的所有属性。

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

Java DOM4J Parser - Parse XML Document

使用DOM4J的步骤

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

  • 导入与XML相关的包。

  • 创建一个SAXReader。

  • 从文件或流创建文档。

  • 通过调用document.selectNodes()获取使用XPath Expression获取所需的节点

  • 提取根元素。

  • 迭代节点列表。

  • 检查属性。

  • 检查子元素。

Import XML-related packages

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

创建一个DocumentBuilder (Create a DocumentBuilder)

SAXBuilder saxBuilder = new SAXBuilder();

从文件或流创建文档

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

提取根元素

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.iowiki.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.iowiki.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.iowiki.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.iowiki.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>
↑回到顶部↑
WIKI教程 @2018