Java StAX 解析器 - 修改 XML 文档



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

使用 Java StAX 解析器修改 XML

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

  • 步骤 1:创建 XMLInputFactory 实例
  • 步骤 2:读取 XML
  • 步骤 3:解析 XML
  • 步骤 4:修改 XML 内容
  • 步骤 5:创建 XMLStreamReader 对象
  • 步骤 6:将更新后的内容写入 XML 文件

关于前三个步骤,请参考本节的解析 XML 文档

步骤 4:修改 XML 内容

完成前三个步骤后,我们的 XML 文件就在 XMLEventReader 对象中。由于我们无法随机访问 XML 元素,因此我们可以同时读取和写入 XML 内容。在这里,更新仅仅意味着创建新的事件并将它们添加到旧事件的位置。

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

XMLEventFactory eventFactory=XMLEventFactory.newInstance();

关于步骤 5 和 6,请参考本节的创建 XML 文档章节。

更新文本内容

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

示例

这是我们需要更新学号为 593 的学生成绩的studentData.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>

在下面的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>

向现有 XML 文件添加元素

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

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

示例

在下面的AddXMLElements.java程序中,我们将所有事件添加到 XMLEventWriter,直到最后一个学生元素。我们在末尾添加了新的学生元素,然后关闭了根元素。为了找到添加新元素的确切位置,我们使用了 peek() 方法,因为它只是显示了 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();
      }
   }
}

输出

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

<?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>
广告
© . All rights reserved.