Java Xml 简明教程

Java StAX Parser - Modify XML Document

Java StAX 解析器是一个 Java API,该 API 提供用于解析和修改 XML 文档的接口、类和方法。无法使用 StAX 解析器随机访问 XML 元素,因此我们需要在解析器解析 XML 文档时存储所需数据。我们可以使用 XMLEventReader 来读取 XML 文档,并同时使用 XMLEventWriter 来编写更新后的内容。

Modify XML Using Java StAX Parser

我们可以通过以下步骤使用 StAX 解析器在 Java 中修改 XML 文档−

  1. *步骤 1:*创建 XMLInputFactory 实例

  2. 步骤 2: 读取 XML

  3. *第 3 步:*解析 XML

  4. *第 4 步:*修改 XML 内容

  5. *第 5 步:*创建 XMLStreamReader 对象

  6. *第 6 步:*将更新后的内容写入 XML 文件

请参考本节的 Parse XML Document 了解前三个步骤

Step 4: Modifying the XML content

在执行前三个步骤后,我们的 XML 文件就在 XMLEventReader 对象中。由于我们无法随机访问 XML 元素,因此我们可以同时读取和写入 XML 内容。这里,更新表示简单地创建新事件并将其添加到旧事件的位置。

要创建任何 XMLEvent,我们应首先获取 XMLEventFactory 的实例。使用 XMLEventFactory,我们可以添加新元素和属性。

XMLEventFactory eventFactory=XMLEventFactory.newInstance();

有关步骤 5 和 6,请参阅本节中的 Create XML Document 章节。

Updating Text Content

XMLEventFactory 的 createCharacters("text") 方法使用指定的文本创建字符内容并返回 Characters 事件。可以使用 add() 函数将此事件添加到 XMLEventWriter。

Example

以下为 studentData.xml 文件,我们需在此文件中更新学号为 593 的学生的成绩。

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

在以下 UpdatingTextContent.java 程序中,我们使用了两个布尔变量 studentFound 和 marksFound 来确定学号为 593 的学生。我们向 XMLEventWriter 添加了所有事件,但学号为 593 的学生的成绩的 Characters 事件除外。我们正在为此学生创建一个新 Characters 事件,并将其添加到 XMLEventWriter。

import java.io.FileReader;
import java.io.StringWriter;
import javax.xml.namespace.QName;
import javax.xml.stream.XMLEventFactory;
import javax.xml.stream.XMLEventReader;
import javax.xml.stream.XMLEventWriter;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLOutputFactory;
import javax.xml.stream.XMLStreamConstants;
import javax.xml.stream.events.Attribute;
import javax.xml.stream.events.StartElement;
import javax.xml.stream.events.XMLEvent;

public class UpdatingTextContent {
   public static void main(String[] args) {
      try {

         //Creating XMLInputFactory instance
         XMLInputFactory factory = XMLInputFactory.newInstance();

         //Reading the XML
         FileReader fileReader = new FileReader("studentData.xml");

         //Parsing the XML
         XMLEventReader eventReader =
         factory.createXMLEventReader(fileReader);

         //Updating text content
         StringWriter stringWriter = new StringWriter();
         XMLOutputFactory outFactory = XMLOutputFactory.newInstance();
         XMLEventWriter eventWriter = outFactory.createXMLEventWriter(stringWriter);
         XMLEventFactory eventFactory=XMLEventFactory.newInstance();

         boolean studentFound=false;
         boolean marksFound=false;
         while(eventReader.hasNext()) {
            XMLEvent event = eventReader.nextEvent();
            if(event.getEventType()==XMLStreamConstants.START_ELEMENT) {
               StartElement startElement = event.asStartElement();
               String qName = startElement.getName().getLocalPart();
               Attribute attr = startElement.getAttributeByName(new QName("rollno"));

               if (qName.equalsIgnoreCase("student") && attr.getValue().equals("593")) {
                  studentFound=true;
                  }
               if (qName.equalsIgnoreCase("marks") && studentFound) {
            	  studentFound = false;
            	  marksFound=true;
               }
            }
            if(event.getEventType()==XMLStreamConstants.CHARACTERS && marksFound) {
               eventWriter.add(eventFactory.createCharacters("64"));
               marksFound=false;
            }
            else {
               eventWriter.add(event);
            }
         }
         String xmlString = stringWriter.getBuffer().toString();
         System.out.println(xmlString);

      } catch (Exception e) {
         e.printStackTrace();
      }
   }
}

输出窗口显示了学生数据,成绩已修改为学号为 593 的学生。

<?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>64</marks>
   </student>
</class>

Adding Elements to Existing XML File

XMLEventWriter 的 add(XMLEvent event) 函数将事件添加到在创建 XMLEventWriter 时指定的 Writer 或 OutputStream。添加一个新的 StartElement 事件将打开新的命名空间范围,当添加 EndElement 事件时,它将关闭。

使用我们在前面的示例中讨论过的相同的 studentData.xml 文件,我们将添加具有所有必要信息的新学生元素。

Example

在以下 AddXMLElements.java 程序中,我们已将所有事件都添加到 XMLEventWriter 直到最后一个学生元素。我们在末尾添加了新的学生元素,然后关闭了根元素。为了找到添加新元素的确切位置,我们使用了 peek() 方法,因为它只显示窥探事件,而不是从流中读取窥探事件。

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileReader;
import java.io.StringWriter;
import javax.xml.stream.XMLEventFactory;
import javax.xml.stream.XMLEventReader;
import javax.xml.stream.XMLEventWriter;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLOutputFactory;
import javax.xml.stream.XMLStreamConstants;
import javax.xml.stream.XMLStreamReader;
import javax.xml.stream.events.XMLEvent;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stax.StAXSource;
import javax.xml.transform.stream.StreamResult;

public class AddXMLElements {
   public static void main(String[] args) {
      try {

    	 //Creating XMLInputFactory instance
         XMLInputFactory factory = XMLInputFactory.newInstance();

         //Reading the XML
         FileReader fileReader = new FileReader("studentData.xml");

         //Parsing the XML
         XMLEventReader eventReader =
         factory.createXMLEventReader(fileReader);

         //Modifying the XML content
         StringWriter stringWriter = new StringWriter();
         XMLOutputFactory outFactory = XMLOutputFactory.newInstance();
         XMLEventWriter eventWriter = outFactory.createXMLEventWriter(stringWriter);
         XMLEventFactory eventFactory=XMLEventFactory.newInstance();

         while(eventReader.hasNext()) {
            XMLEvent event = eventReader.nextEvent();
            if(event.getEventType()==XMLStreamConstants.END_ELEMENT &&
            		eventReader.peek().getEventType()==XMLStreamConstants.END_DOCUMENT ) {

               eventWriter.add(eventFactory.createStartElement("", "", "student"));
               eventWriter.add(eventFactory.createAttribute("rollno", "693"));

               eventWriter.add(eventFactory.createStartElement("", "", "firstname"));
               eventWriter.add(eventFactory.createCharacters("Daniel"));
               eventWriter.add(eventFactory.createEndElement("", "", "firstname"));

               eventWriter.add(eventFactory.createStartElement("", "", "lastname"));
               eventWriter.add(eventFactory.createCharacters("Wesley"));
               eventWriter.add(eventFactory.createEndElement("", "", "lastname"));

               eventWriter.add(eventFactory.createStartElement("", "", "nickname"));
               eventWriter.add(eventFactory.createCharacters("Dany"));
               eventWriter.add(eventFactory.createEndElement("", "", "nickname"));

               eventWriter.add(eventFactory.createStartElement("", "", "marks"));
               eventWriter.add(eventFactory.createCharacters("75"));
               eventWriter.add(eventFactory.createEndElement("", "", "marks"));

               eventWriter.add(eventFactory.createEndElement("", "", "student"));
            }
            else {
               eventWriter.add(event);
            }
         }

         //Creating XMLStreamReader object
         String xmlString = stringWriter.getBuffer().toString();
         ByteArrayInputStream input = new ByteArrayInputStream(xmlString.getBytes("UTF-8"));
         stringWriter.close();
         XMLStreamReader streamReader =
                 factory.createXMLStreamReader(input);

         //writing the updated content into XML file
         TransformerFactory transformerFactory = TransformerFactory.newInstance();
         Transformer transformer = transformerFactory.newTransformer();
         StAXSource source = new StAXSource(streamReader);
         StreamResult result = new StreamResult(new File("studentData.xml"));
         transformer.transform(source, result);

         System.out.println(xmlString);

      } catch (Exception e) {
         e.printStackTrace();
      }
   }
}

Output

这是添加新学生信息后输出文件的内容−

<?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>
  <student rollno="693">
    <firstname>Daniel</firstname>
    <lastname>Wesley</lastname>
    <nickname>Dany</nickname>
    <marks>75</marks>
  </student>
</class>