欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

基于Java實現XML文件的解析與更新

 更新時間:2022年03月22日 10:22:09   作者:Linux中國  
配置文件可以有很多種格式,包括?INI、JSON、YAML?和?XML。每一種編程語言解析這些格式的方式都不同。本文將通過Java語言實現XML文件的解析與更新,需要的可以參考一下

在你使用 Java 編寫軟件時實現持久化配置。

當你編寫一個應用時,你通常都會希望用戶能夠定制化他們和應用交互的方式,以及應用與系統(tǒng)進行交互的方式。這種方式通常被稱為 “偏好preference” 或者 “設置setting”,它們被保存在一個 “偏好文件” 或者 “配置文件” 中,有時也直接簡稱為 “配置config”。配置文件可以有很多種格式,包括 INI、JSON、YAML 和 XML。每一種編程語言解析這些格式的方式都不同。本文主要討論,當你在使用 Java 編程語言 來編寫軟件時,實現持久化配置的方式。

選擇一個格式

編寫配置文件是一件相當復雜的事情。我曾經試過把配置項使用逗號分隔保存在一個文本文件里,也試過把配置項保存在非常詳細的 YAML 和 XML 中。對于配置文件來說,最重要是要有一致性和規(guī)律性,它們使你可以簡單快速地編寫代碼,從配置文件中解析出數據;同時,當用戶決定要做出修改時,很方便地保存和更新配置。

目前有 幾種流行的配置文件格式。對于大多數常見的配置文件格式,Java 都有對應的庫library。在本文中,我將使用 XML 格式。對于一些項目,你可能會選擇使用 XML,因為它的一個突出特點是能夠為包含的數據提供大量相關的元數據,而在另外一些項目中,你可能會因為 XML 的冗長而不選擇它。在 Java 中使用 XML 是非常容易的,因為它默認包含了許多健壯的 XML 庫。

XML 基礎

討論 XML 可是一個大話題。我有一本關于 XML 的書,它有超過 700 頁的內容。幸運的是,使用 XML 并不需要非常了解它的諸多特性。就像 HTML 一樣,XML 是一個帶有開始和結束標記的分層標記語言,每一個標記(標簽)內可以包含零個或更多數據。下面是一個 XML 的簡單示例片段:

<xml>
      <node>
        <element>Penguin</element>
      </node>
    </xml>

在這個 自我描述的self-descriptive 例子中,XML 解析器使用了以下幾個概念:

  • 文檔Document: 標簽標志著一個 文檔 的開始, 標簽標志著這個文檔的結束。
  • 節(jié)點Node: 標簽代表了一個 節(jié)點。
  • 元素Element: Penguin 中,從開頭的 < 到最后的 > 表示了一個 元素。
  • 內容Content: 在 元素里,字符串 Penguin 就是 內容。

不管你信不信,只要了解了以上幾個概念,你就可以開始編寫、解析 XML 文件了。

創(chuàng)建一個示例配置文件

要學習如何解析 XML 文件,只需要一個極簡的示例文件就夠了。假設現在有一個配置文件,里面保存的是關于一個圖形界面窗口的屬性:

<xml>
      <window>
        <theme>Dark</theme>
        <fullscreen>0</fullscreen>
        <icons>Tango</icons>
    </window>
    </xml>

創(chuàng)建一個名為 ~/.config/DemoXMLParser 的目錄:

$ mkdir ~/.config/DemoXMLParser

在 Linux 中,~/.config 目錄是存放配置文件的默認位置,這是在 自由桌面工作組 的規(guī)范中定義的。如果你正在使用一個不遵守 自由桌面工作組Freedesktop標準的操作系統(tǒng),你也仍然可以使用這個目錄,只不過你需要自己創(chuàng)建這些目錄了。

復制 XML 的示例配置文件,粘貼并保存為 ~/.config/DemoXMLParser/myconfig.xml 文件。

使用 Java 解析 XML

如果你是 Java 的初學者,你可以先閱讀我寫的 面向 Java 入門開發(fā)者的 7 個小技巧。一旦你對 Java 比較熟悉了,打開你最喜愛的集成開發(fā)工具(IDE),創(chuàng)建一個新工程。我會把我的新工程命名為 myConfigParser。

剛開始先不要太關注依賴導入和異常捕獲這些,你可以先嘗試用 javax 和 java.io 包里的標準 Java 擴展來實例化一個解析器。如果你使用了 IDE,它會提示你導入合適的依賴。如果沒有,你也可以在文章稍后的部分找到完整的代碼,里面就有完整的依賴列表。

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();

這段示例代碼使用了 java.nio.Paths 類來找到用戶的主目錄,然后在拼接上默認配置文件的路徑。接著,它用 java.io.File 類來把配置文件定義為一個 File 對象。

緊接著,它使用了 javax.xml.parsers.DocumentBuilder 和 javax.xml.parsers.DocumentBuilderFactory 這兩個類來創(chuàng)建一個內部的文檔構造器,這樣 Java 程序就可以導入并解析 XML 數據了。

最后,Java 創(chuàng)建一個叫 doc 的文檔對象,并且把 configFile 文件加載到這個對象里。通過使用 org.w3c.dom 包,它讀取并規(guī)范化了 XML 數據。

基本上就是這樣啦。理論上來講,你已經完成了數據解析的工作??墒?,如果你不能夠訪問數據的話,數據解析也沒有多少用處嘛。所以,就讓我們再來寫一些查詢,從你的配置中讀取重要的屬性值吧。

使用 Java 訪問 XML 的值

從你已經讀取的 XML 文檔中獲取數據,其實就是要先找到一個特定的節(jié)點,然后遍歷它包含的所有元素。通常我們會使用多個循環(huán)語句來遍歷節(jié)點中的元素,但是為了保持代碼可讀性,我會盡可能少地使用循環(huán)語句:

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());
     }
    }

這段示例代碼使用了 org.w3c.dom.NodeList 類,創(chuàng)建了一個名為 nodes 的 NodeList 對象。這個對象包含了所有名字匹配字符串 window 的子節(jié)點,實際上這樣的節(jié)點只有一個,因為本文的示例配置文件中只配置了一個。

緊接著,它使用了一個 for 循環(huán)來遍歷 nodes 列表。具體過程是:根據節(jié)點出現的順序逐個取出,然后交給一個 if-then 子句處理。這個 if-then 子句創(chuàng)建了一個名為 myelement 的 Element 對象,其中包含了當前節(jié)點下的所有元素。你可以使用例如 getChildNodes 和 getElementById 方法來查詢這些元素,項目中還 記錄了 其他查詢方法。

在這個示例中,每個元素就是配置的鍵。而配置的值儲存在元素的內容中,你可以使用 .getTextContent 方法來提取出配置的值。

在你的 IDE 中運行代碼(或者運行編譯后的二進制文件):

$ java ./DemoXMLParser.java
    Property = window
    Theme = Dark
    Fullscreen = 0
    Icon set = Tango

下面是完整的代碼示例:

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

使用 Java 更新 XML

用戶時不時地會改變某個偏好項,這時候 org.w3c.dom 庫就可以幫助你更新某個 XML 元素的內容。你只需要選擇這個 XML 元素,就像你讀取它時那樣。不過,此時你不再使用 .getTextContent 方法,而是使用 .setTextContent 方法。

updatePref = myelement.getElementsByTagName("fullscreen").item(0);
    updatePref.setTextContent("1");
    System.out.println("Updated fullscreen to " + myelement.getElementsByTagName("fullscreen").item(0).getTextContent());

這么做會改變應用程序內存中的 XML 文檔,但是還沒有把數據寫回到磁盤上。配合使用 javax 和 w3c 庫,你就可以把讀取到的 XML 內容寫回到配置文件中。

TransformerFactory transformerFactory = TransformerFactory.newInstance();
    Transformer xtransform;
    xtransform = transformerFactory.newTransformer();
    DOMSource mydom = new DOMSource(doc);
    StreamResult streamResult = new StreamResult(configFile);
    xtransform.transform(mydom, streamResult);

這么做會沒有警告地寫入轉換后的數據,并覆蓋掉之前的配置。

下面是完整的代碼,包括更新 XML 的操作:

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

如何保證配置不出問題

編寫配置文件看上去是一個還挺簡單的任務。一開始,你可能會用一個簡單的文本格式,因為你的應用程序只要寥寥幾個配置項而已。但是,隨著你引入了更多的配置項,讀取或者寫入錯誤的數據可能會給你的應用程序帶來意料之外的錯誤。一種幫助你保持配置過程安全、不出錯的方法,就是使用類似 XML 的規(guī)范格式,然后依靠你用的編程語言的內置功能來處理這些復雜的事情。

這也正是我喜歡使用 Java 和 XML 的原因。每當我試圖讀取錯誤的配置值時,Java 就會提醒我。通常,這是由于我在代碼中試圖獲取的節(jié)點,并不存在于我期望的 XML 路徑中。XML 這種高度結構化的格式幫助了代碼保持可靠性,這對用戶和開發(fā)者來說都是有好處的。

以上就是基于Java實現XML文件的解析與更新的詳細內容,更多關于Java XML解析 更新的資料請關注腳本之家其它相關文章!

相關文章

  • java中response對象用法實例分析

    java中response對象用法實例分析

    這篇文章主要介紹了java中response對象用法,結合實例形式分析了Java中response對象的功能及具體使用技巧,需要的朋友可以參考下
    2015-12-12
  • Java web xml文件讀取解析方式

    Java web xml文件讀取解析方式

    這篇文章主要介紹了Java web xml文件讀取解析方式,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-03-03
  • 輕松掌握Java享元模式

    輕松掌握Java享元模式

    這篇文章主要幫助大家輕松掌握Java享元模式,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2016-09-09
  • 淺聊一下Spring中Bean的配置細節(jié)

    淺聊一下Spring中Bean的配置細節(jié)

    我們知道,當寫完一個普通的 Java 類后,想讓 Spring IoC 容器在創(chuàng)建類的實例對象時使用構造方法完成實例對象的依賴注入,那么就需要在配置元數據中寫好類的 Bean 定義,包括各種標簽的屬性。所以本文我們來說說這其中的配置細節(jié),需要的朋友可以參考下
    2023-07-07
  • 解決mybatis竟然報Invalid value for getInt()的問題

    解決mybatis竟然報Invalid value for getInt()的問題

    使用mybatis遇到一個非常奇葩的問題,總是報Invalid value for getInt()的問題,怎么解決呢?下面小編通過場景分析給大家代來了mybatis報Invalid value for getInt()的解決方法,感興趣的朋友參考下吧
    2021-10-10
  • Java 如何從list中刪除符合條件的數據

    Java 如何從list中刪除符合條件的數據

    這篇文章主要介紹了Java 如何從list中刪除符合條件的數據,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-11-11
  • springboot?+rabbitmq+redis實現秒殺示例

    springboot?+rabbitmq+redis實現秒殺示例

    本文主要介紹了springboot?+rabbitmq+redis實現秒殺示例,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2022-07-07
  • Java中的BlockingQueue接口源碼解析

    Java中的BlockingQueue接口源碼解析

    這篇文章主要介紹了Java中的BlockingQueue接口源碼解析,BlockingQueue接口表示阻塞隊列,是Java并發(fā)包中阻塞隊列的接口定義規(guī)范,阻塞隊列意味著對于該隊列的操作是線程安全的,當多個線程存放元素進入隊列或者從隊列中取出元素都是線程安全的,需要的朋友可以參考下
    2023-11-11
  • Spring:bean注入--Set方法注入

    Spring:bean注入--Set方法注入

    這篇文章主要給大家總結介紹了關于Spring注入Bean的一些方式,文中通過示例代碼介紹的非常詳細,對大家學習或者使用Spring具有一定的參考學習價值,需要的朋友們下面來一起學習學習吧
    2021-07-07
  • IDEA插件(BindED)之查看class文件的十六進制

    IDEA插件(BindED)之查看class文件的十六進制

    這篇文章主要介紹了IDEA插件(BindED)之查看class文件的十六進制,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-12-12

最新評論