Java SAX 解析器 - 修改 XML 文档



Java SAX 解析器是一个 Java API,可用于解析和修改 XML 文档。要使用 SAX 解析器修改任何 XML 文档,我们必须将数据存储在任何数据结构中,因为我们无法回退,因为它只有向前只读访问权限。在本章中,我们将详细了解如何读取和修改现有的 XML 文档。

使用 Java SAX 解析器修改 XML

  • 步骤 1:实现 Handler 类
  • 步骤 2:创建 SAXParser 对象
  • 步骤 3:读取 XML
  • 步骤 4:创建 Handler 类的对象
  • 步骤 5:解析 XML 文档
  • 步骤 6:将更新后的内容写入文件

请参考本节的解析 XML 文档章节了解前五个步骤。

步骤 6:将更新后的内容写入文件

可以使用 FileWriter 对象的 write() 方法将更新后的内容写入文件,如下所示:

FileWriter filewriter = new FileWriter("newfile.xml");
filewriter.write("content_here");

修改 XML 文件

SAX 解析器不会像 DOM 提供的那样提供对元素的随机访问。我们可以实现实现 DefaultHandler 的 Handler 类中的回调方法,以创建并将新元素添加到已存在的 XML 文档中。

示例

在这个示例中,我们将了解如何通过向 student 元素添加 result 元素来修改 studentData.xml 文件。以下是我们需要通过在 </marks> 标记的末尾附加 <Result>Pass<Result/> 来修改的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>singn</lastname>
      <nickname>jazz</nickname>
      <marks>90</marks>
   </student>
</class>

在下面的ModifyXML.java 程序中,我们创建了 SAXParser 对象并解析了输入文件。我们已经使用必要的回调方法和 writeFile() 方法实现了 Handler 类,以将更新后的内容写入文件。我们使用了字符串数组来存储并将内容写入文件。

import java.io.*;
import org.xml.sax.*;
import javax.xml.parsers.*;
import org.xml.sax.helpers.DefaultHandler;

//Implementing a Handler class
class UserDemoHandler extends DefaultHandler {
	
   static String displayText[] = new String[1000];
   static int numberLines = 0;
   static String indentation = "";
   
   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");
	  }
   }
   
   public void writeFile(FileWriter filewriter) throws IOException {
	   
      for(int loopIndex = 0; loopIndex < numberLines; loopIndex++) {
         filewriter.write(displayText[loopIndex].toCharArray());
	     filewriter.write('\n');
	     System.out.println(displayText[loopIndex].toString());
	  }
      filewriter.close();
   }
}

public class ModifyXML extends DefaultHandler {
   public static void main(String args[]) {
      try {
    	  
    	 //Creating SAXParser object 
         SAXParserFactory factory = SAXParserFactory.newInstance();
         SAXParser saxParser = factory.newSAXParser();
         
         //Reading the XML 
         File inputFile = new File("src/input.txt");
         
         //Creating object for Handler class
         UserDemoHandler userHandler = new UserDemoHandler();
         
         //Parsing the XML
         saxParser.parse(inputFile, userHandler);
         
         //Writing the updated content into file
         FileWriter filewriter = new FileWriter("src/newfile.xml");
         userHandler.writeFile(filewriter);
         
      }
      catch (Exception e) {
         e.printStackTrace(System.err);
      }
   }
}

输出窗口显示在向每个 student 元素添加 result 元素后 XML 文档的更新内容。

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