目錄
選擇一個格式
XML 基礎
建立一個範例設定檔
使用 Java 解析 XML
使用 Java 访问 XML 的值
使用 Java 更新 XML
如何保证配置不出问题
首頁 Java java教程 Java持久化XML檔怎麼配置

Java持久化XML檔怎麼配置

May 04, 2023 am 09:40 AM
java xml

<h4 id="選擇一個格式">選擇一個格式</h4> <p>撰寫設定檔是一件相當複雜的事情。我曾經試過把設定項使用逗號分隔保存在一個文字檔案裡,也試過把設定項保存在非常詳細的 YAML 和 XML 中。對於設定檔來說,最重要是要有一致性和規律性,它們使你可以簡單快速地編寫程式碼,從設定檔中解析出資料;同時,當使用者決定要做出修改時,很方便地保存和更新配置。 </p> <p>目前有 幾種流行的設定檔格式。對於大多數常見的設定檔格式,Java 都有對應的函式庫library。在本文中,我將使用 XML 格式。對於某些項目,你可能會選擇使用 XML,因為它的一個突出特點是能夠為包含的數據提供大量相關的元數據,而在其他一些項目中,你可能會因為 XML 的冗長而不選擇它。在 Java 中使用 XML 是非常容易的,因為它預設包含了許多健壯的 XML 程式庫。 </p> <h4 id="XML-基礎">XML 基礎</h4> <p>討論 XML 可是一個大話題。我有一本關於 XML 的書,它有超過 700 頁的內容。幸運的是,使用 XML 並不需要非常了解它的許多特性。就像 HTML 一樣,XML 是一個帶有開始和結束標記的分層標記語言,每個標記(標籤)內可以包含零個或更多資料。以下是一個XML 的簡單範例片段:</p><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class='brush:php;toolbar:false;'><xml> <node> <element>Penguin</element> </node> </xml></pre><div class="contentsignin">登入後複製</div></div><p>在這個 自我描述的self-descriptive 範例中,XML 解析器使用了以下幾個概念:</p><ul class=" list-paddingleft-2"><li><p>文檔Document:<code><xml></code> 標籤標誌著一個 文檔 的開始,<code></xml></code> 標籤標誌著這個文件的結束。 </p></li><li><p>節點Node:<code><node></code> 標籤代表了一個 節點。 </p></li><li><p>元素Element:<code><element>Penguin</element></code> 中,從開頭的 <code><</code> 到最後的 <code>&gt ;</code> 表示了一個 元素。 </p></li><li><p>內容Content: 在 <code><element></code> 元素裡,字串 <code>Penguin</code> 就是 內容。 </p></li></ul><p>不管你信不信,只要了解了以上幾個概念,你就可以開始寫、解析 XML 檔了。 </p><h4 id="建立一個範例設定檔">建立一個範例設定檔</h4><p>要學習如何解析 XML 文件,只需要一個極簡的範例文件就夠了。假設現在有一個設定文件,裡面保存的是關於一個圖形介面視窗的屬性:</p><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class='brush:php;toolbar:false;'><xml> <window> <theme>Dark</theme> <fullscreen>0</fullscreen> <icons>Tango</icons> </window> </xml></pre><div class="contentsignin">登入後複製</div></div><p>建立一個名為 <code>~/.config/DemoXMLParser</code> 的目錄:</p><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class='brush:php;toolbar:false;'>$ mkdir ~/.config/DemoXMLParser</pre><div class="contentsignin">登入後複製</div></div><p>在Linux 中,<code>~/.config</code> 目錄是存放設定檔的預設位置,這是在 自由桌面工作組 的規格中定義的。如果你正在使用一個不遵守 自由桌面工作小組Freedesktop標準的作業系統,你也仍然可以使用這個目錄,只不過你需要自己創建這些目錄了。 </p><p>複製 XML 的範例設定文件,貼上並儲存為 <code>~/.config/DemoXMLParser/myconfig.xml</code> 檔案。 </p><h4 id="使用-Java-解析-XML">使用 Java 解析 XML</h4><p>如果你是 Java 的初學者,你可以先閱讀我寫的 針對 Java 入門開發者的 7 個小技巧。一旦你對 Java 比較熟悉了,打開你最喜愛的整合開發工具(IDE),創建一個新工程。我會把我的新工程命名為 <code>myConfigParser</code>。 </p><p>剛開始先不要太專注於依賴導入和異常捕獲這些,你可以先嘗試用 <code>javax</code> 和 <code>java.io</code> 包裡的標準Java 擴充來實例化一個解析器。如果你使用了 IDE,它會提示你匯入適當的依賴。如果沒有,你也可以在文章稍後的部分找到完整的程式碼,裡面就有完整的依賴清單。 </p><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class='brush:php;toolbar:false;'>Path configPath = Paths.get(System.getProperty("user.home"), ".config", "DemoXMLParser"); File configFile = new File(configPath.toString(), "myconfig.xml"); DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); DocumentBuilder builder = null; builder = factory.newDocumentBuilder(); Document doc = null; doc = builder.parse(configFile); doc.getDocumentElement().normalize();</pre><div class="contentsignin">登入後複製</div></div><p>這段範例程式碼使用了 <code>java.nio.Paths</code> 類別來找到使用者的主目錄,然後在拼接上預設設定檔的路徑。接著,它用 <code>java.io.File</code> 類別來定義設定檔為一個 <code>File</code> 物件。 </p><p>緊接著,它使用了 <code>javax.xml.parsers.DocumentBuilder</code> 和 <code>javax.xml.parsers.DocumentBuilderFactory</code> 這兩個類別來建立一個內部的文件建構器,這樣Java 程式就可以匯入並解析XML 資料了。 </p><p>最後,Java 建立一個叫 <code>doc</code> 的文檔對象,並且把 <code>configFile</code> 檔案載入到這個物件裡。透過使用 <code>org.w3c.dom</code> 套件,它讀取並標準化了 XML 資料。 </p><p>基本上就是這樣啦。理論上來講,你已經完成了資料解析的工作。可是,如果你無法存取資料的話,資料解析也沒有多少用處嘛。所以,就讓我們再來寫一些查詢,從你的配置中讀取重要的屬性值吧。 </p><h4 id="使用-Java-访问-XML-的值">使用 Java 访问 XML 的值</h4><p>从你已经读取的 XML 文档中获取数据,其实就是要先找到一个特定的节点,然后遍历它包含的所有元素。通常我们会使用多个循环语句来遍历节点中的元素,但是为了保持代码可读性,我会尽可能少地使用循环语句:</p><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class='brush:php;toolbar:false;'>NodeList nodes = doc.getElementsByTagName("window"); for (int i = 0; i < nodes.getLength(); i++) { Node mynode = nodes.item(i); System.out.println("Property = " + mynode.getNodeName()); if (mynode.getNodeType() == Node.ELEMENT_NODE) { Element myelement = (Element) mynode; System.out.println("Theme = " + myelement.getElementsByTagName("theme").item(0).getTextContent()); System.out.println("Fullscreen = " + myelement.getElementsByTagName("fullscreen").item(0).getTextContent()); System.out.println("Icon set = " + myelement.getElementsByTagName("icons").item(0).getTextContent()); } }</pre><div class="contentsignin">登入後複製</div></div><p>这段示例代码使用了 <code>org.w3c.dom.NodeList</code> 类,创建了一个名为 <code>nodes</code> 的 <code>NodeList</code> 对象。这个对象包含了所有名字匹配字符串 <code>window</code> 的子节点,实际上这样的节点只有一个,因为本文的示例配置文件中只配置了一个。</p><p>紧接着,它使用了一个 <code>for</code> 循环来遍历 <code>nodes</code> 列表。具体过程是:根据节点出现的顺序逐个取出,然后交给一个 <code>if-then</code> 子句处理。这个 <code>if-then</code> 子句创建了一个名为 <code>myelement</code> 的 <code>Element</code> 对象,其中包含了当前节点下的所有元素。你可以使用例如 <code>getChildNodes</code> 和 <code>getElementById</code> 方法来查询这些元素,项目中还 记录了 其他查询方法。</p><p>在这个示例中,每个元素就是配置的键。而配置的值储存在元素的内容中,你可以使用 <code>.getTextContent</code> 方法来提取出配置的值。</p><p>在你的 IDE 中运行代码(或者运行编译后的二进制文件):</p><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class='brush:php;toolbar:false;'>$ java ./DemoXMLParser.java Property = window Theme = Dark Fullscreen = 0 Icon set = Tango</pre><div class="contentsignin">登入後複製</div></div><p>下面是完整的代码示例:</p><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class='brush:php;toolbar:false;'>package myConfigParser; import java.io.File; import java.io.IOException; import java.nio.file.Path; import java.nio.file.Paths; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.NamedNodeMap; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.xml.sax.SAXException; public class ConfigParser { public static void main(String[] args) { Path configPath = Paths.get(System.getProperty("user.home"), ".config", "DemoXMLParser"); File configFile = new File(configPath.toString(), "myconfig.xml"); DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); DocumentBuilder builder = null; try { builder = factory.newDocumentBuilder(); } catch (ParserConfigurationException e) { e.printStackTrace(); } Document doc = null; try { doc = builder.parse(configFile); } catch (SAXException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } doc.getDocumentElement().normalize(); NodeList nodes = doc.getElementsByTagName("window"); for (int i = 0; i < nodes.getLength(); i++) { Node mynode = nodes.item(i); System.out.println("Property = " + mynode.getNodeName()); if (mynode.getNodeType() == Node.ELEMENT_NODE) { Element myelement = (Element) mynode; System.out.println("Theme = " + myelement.getElementsByTagName("theme").item(0).getTextContent()); System.out.println("Fullscreen = " + myelement.getElementsByTagName("fullscreen").item(0).getTextContent()); System.out.println("Icon set = " + myelement.getElementsByTagName("icons").item(0).getTextContent()); } // close if } // close for } // close method } //close class</pre><div class="contentsignin">登入後複製</div></div><h4 id="使用-Java-更新-XML">使用 Java 更新 XML</h4><p>用户时不时地会改变某个偏好项,这时候 <code>org.w3c.dom</code> 库就可以帮助你更新某个 XML 元素的内容。你只需要选择这个 XML 元素,就像你读取它时那样。不过,此时你不再使用 <code>.getTextContent</code> 方法,而是使用 <code>.setTextContent</code> 方法。</p><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class='brush:php;toolbar:false;'>updatePref = myelement.getElementsByTagName("fullscreen").item(0); updatePref.setTextContent("1"); System.out.println("Updated fullscreen to " + myelement.getElementsByTagName("fullscreen").item(0).getTextContent());</pre><div class="contentsignin">登入後複製</div></div><p>这么做会改变应用程序内存中的 XML 文档,但是还没有把数据写回到磁盘上。配合使用 <code>javax</code> 和 <code>w3c</code> 库,你就可以把读取到的 XML 内容写回到配置文件中。</p><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class='brush:php;toolbar:false;'>TransformerFactory transformerFactory = TransformerFactory.newInstance(); Transformer xtransform; xtransform = transformerFactory.newTransformer(); DOMSource mydom = new DOMSource(doc); StreamResult streamResult = new StreamResult(configFile); xtransform.transform(mydom, streamResult);</pre><div class="contentsignin">登入後複製</div></div><p>这么做会没有警告地写入转换后的数据,并覆盖掉之前的配置。</p><p>下面是完整的代码,包括更新 XML 的操作:</p><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class='brush:php;toolbar:false;'>package myConfigParser; import java.io.File; import java.io.IOException; import java.nio.file.Path; import java.nio.file.Paths; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerException; import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.xml.sax.SAXException; public class ConfigParser { public static void main(String[] args) { Path configPath = Paths.get(System.getProperty("user.home"), ".config", "DemoXMLParser"); File configFile = new File(configPath.toString(), "myconfig.xml"); DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); DocumentBuilder builder = null; try { builder = factory.newDocumentBuilder(); } catch (ParserConfigurationException e) { // TODO Auto-generated catch block e.printStackTrace(); } Document doc = null; try { doc = builder.parse(configFile); } catch (SAXException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } doc.getDocumentElement().normalize(); Node updatePref = null; // NodeList nodes = doc.getChildNodes(); NodeList nodes = doc.getElementsByTagName("window"); for (int i = 0; i < nodes.getLength(); i++) { Node mynode = nodes.item(i); System.out.println("Property = " + mynode.getNodeName()); if (mynode.getNodeType() == Node.ELEMENT_NODE) { Element myelement = (Element) mynode; System.out.println("Theme = " + myelement.getElementsByTagName("theme").item(0).getTextContent()); System.out.println("Fullscreen = " + myelement.getElementsByTagName("fullscreen").item(0).getTextContent()); System.out.println("Icon set = " + myelement.getElementsByTagName("icons").item(0).getTextContent()); updatePref = myelement.getElementsByTagName("fullscreen").item(0); updatePref.setTextContent("2"); System.out.println("Updated fullscreen to " + myelement.getElementsByTagName("fullscreen").item(0).getTextContent()); } // close if }// close for // write DOM back to the file TransformerFactory transformerFactory = TransformerFactory.newInstance(); Transformer xtransform; DOMSource mydom = new DOMSource(doc); StreamResult streamResult = new StreamResult(configFile); try { xtransform = transformerFactory.newTransformer(); xtransform.transform(mydom, streamResult); } catch (TransformerException e) { e.printStackTrace(); } } // close method } //close class</pre><div class="contentsignin">登入後複製</div></div><h4 id="如何保证配置不出问题">如何保证配置不出问题</h4> <p>编写配置文件看上去是一个还挺简单的任务。一开始,你可能会用一个简单的文本格式,因为你的应用程序只要寥寥几个配置项而已。但是,随着你引入了更多的配置项,读取或者写入错误的数据可能会给你的应用程序带来意料之外的错误。一种帮助你保持配置过程安全、不出错的方法,就是使用类似 XML 的规范格式,然后依靠你用的编程语言的内置功能来处理这些复杂的事情。</p> <p>这也正是我喜欢使用 Java 和 XML 的原因。每当我试图读取错误的配置值时,Java 就会提醒我。通常,这是由于我在代码中试图获取的节点,并不存在于我期望的 XML 路径中。XML 这种高度结构化的格式帮助了代码保持可靠性,这对用户和开发者来说都是有好处的。</p>

以上是Java持久化XML檔怎麼配置的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
1 個月前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
1 個月前 By 尊渡假赌尊渡假赌尊渡假赌
威爾R.E.P.O.有交叉遊戲嗎?
1 個月前 By 尊渡假赌尊渡假赌尊渡假赌

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

Java Spring 面試題 Java Spring 面試題 Aug 30, 2024 pm 04:29 PM

在本文中,我們保留了最常被問到的 Java Spring 面試問題及其詳細答案。這樣你就可以順利通過面試。

您如何在PHP中解析和處理HTML/XML? 您如何在PHP中解析和處理HTML/XML? Feb 07, 2025 am 11:57 AM

本教程演示瞭如何使用PHP有效地處理XML文檔。 XML(可擴展的標記語言)是一種用於人類可讀性和機器解析的多功能文本標記語言。它通常用於數據存儲

突破或從Java 8流返回? 突破或從Java 8流返回? Feb 07, 2025 pm 12:09 PM

Java 8引入了Stream API,提供了一種強大且表達力豐富的處理數據集合的方式。然而,使用Stream時,一個常見問題是:如何從forEach操作中中斷或返回? 傳統循環允許提前中斷或返回,但Stream的forEach方法並不直接支持這種方式。本文將解釋原因,並探討在Stream處理系統中實現提前終止的替代方法。 延伸閱讀: Java Stream API改進 理解Stream forEach forEach方法是一個終端操作,它對Stream中的每個元素執行一個操作。它的設計意圖是處

Java程序查找膠囊的體積 Java程序查找膠囊的體積 Feb 07, 2025 am 11:37 AM

膠囊是一種三維幾何圖形,由一個圓柱體和兩端各一個半球體組成。膠囊的體積可以通過將圓柱體的體積和兩端半球體的體積相加來計算。本教程將討論如何使用不同的方法在Java中計算給定膠囊的體積。 膠囊體積公式 膠囊體積的公式如下: 膠囊體積 = 圓柱體體積 兩個半球體體積 其中, r: 半球體的半徑。 h: 圓柱體的高度(不包括半球體)。 例子 1 輸入 半徑 = 5 單位 高度 = 10 單位 輸出 體積 = 1570.8 立方單位 解釋 使用公式計算體積: 體積 = π × r2 × h (4

如何在Spring Tool Suite中運行第一個春季啟動應用程序? 如何在Spring Tool Suite中運行第一個春季啟動應用程序? Feb 07, 2025 pm 12:11 PM

Spring Boot簡化了可靠,可擴展和生產就緒的Java應用的創建,從而徹底改變了Java開發。 它的“慣例慣例”方法(春季生態系統固有的慣例),最小化手動設置

創造未來:零基礎的 Java 編程 創造未來:零基礎的 Java 編程 Oct 13, 2024 pm 01:32 PM

Java是熱門程式語言,適合初學者和經驗豐富的開發者學習。本教學從基礎概念出發,逐步深入解說進階主題。安裝Java開發工具包後,可透過建立簡單的「Hello,World!」程式來實踐程式設計。理解程式碼後,使用命令提示字元編譯並執行程序,控制台上將輸出「Hello,World!」。學習Java開啟了程式設計之旅,隨著掌握程度加深,可創建更複雜的應用程式。

Java 變得簡單:程式設計能力的初學者指南 Java 變得簡單:程式設計能力的初學者指南 Oct 11, 2024 pm 06:30 PM

JavaMadeSimple:ABeginner'sGuidetoProgrammingPower簡介Java是一種強大的程式語言,廣泛應用於從行動應用程式到企業級系統的各種領域。對於初學者來說,Java的文法簡潔易懂,是學習程式設計的理想選擇。基本語法Java使用基於類別的物件導向程式設計範式。類別是將相關資料和行為組織在一起的範本。以下是一個簡單的Java類別範例:publicclassPerson{privateStringname;privateintage;

Java程序將元素插入堆棧的底部 Java程序將元素插入堆棧的底部 Feb 07, 2025 am 11:59 AM

堆棧是遵循LIFO(最後,首先)原理的數據結構。換句話說,我們添加到堆棧中的最後一個元素是第一個要刪除的元素。當我們將(或推)元素添加到堆棧中時,它們就會放在頂部;即最重要的

See all articles