
- Java XML 教程
- Java XML 首頁
- Java XML 概述
- Java XML 解析器
- Java DOM 解析器
- Java DOM 解析器
- 解析 XML 文件
- 查詢 XML 文件
- 建立 XML 文件
- 修改 XML 文件
- Java SAX 解析器
- Java SAX 解析器
- 解析 XML 文件
- 查詢 XML 文件
- 建立 XML 文件
- 修改 XML 文件
- JDOM XML 解析器
- JDOM XML 解析器
- 解析 XML 文件
- 查詢 XML 文件
- 建立 XML 文件
- 修改 XML 文件
- Java StAX 解析器
- Java StAX 解析器
- 解析 XML 文件
- 查詢 XML 文件
- 建立 XML 文件
- 修改 XML 文件
- Java XPath 解析器
- Java XPath 解析器
- 解析 XML 文件
- 查詢 XML 文件
- 建立 XML 文件
- 修改 XML 文件
- Java DOM4J 解析器
- Java DOM4J 解析器
- 解析 XML 文件
- 查詢 XML 文件
- 建立 XML 文件
- 修改 XML 文件
- Java XML 有用資源
- Java XML - 問答
- Java XML - 快速指南
- Java XML - 有用資源
- Java XML - 討論
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>