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>
廣告