iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > 其他教程 >Java持久化XML文件配置解析
  • 338
分享到

Java持久化XML文件配置解析

2024-04-02 19:04:59 338人浏览 独家记忆
摘要

目录前言选择一个格式XML 基础创建一个示例配置文件使用 Java 解析 XML使用 Java 访问 XML 的值使用 Java 更新 XML如何保证配置不出问题前言 当你编写一个应

前言

当你编写一个应用时,你通常都会希望用户能够定制化他们和应用交互的方式,以及应用与系统进行交互的方式。这种方式通常被称为 “偏好preference” 或者 “设置setting”,它们被保存在一个 “偏好文件” 或者 “配置文件” 中,有时也直接简称为 “配置config”。配置文件可以有很多种格式,包括 INI、JSON、YAML 和 XML。每一种编程语言解析这些格式的方式都不同。本文主要讨论,当你在使用 Java 编程语言 来编写软件时,实现持久化配置的方式。

选择一个格式

编写配置文件是一件相当复杂的事情。我曾经试过把配置项使用逗号分隔保存在一个文本文件里,也试过把配置项保存在非常详细的 YAML 和 XML 中。对于配置文件来说,最重要是要有一致性和规律性,它们使你可以简单快速地编写代码,从配置文件中解析出数据;同时,当用户决定要做出修改时,很方便地保存和更新配置。

目前有 几种流行的配置文件格式。对于大多数常见的配置文件格式,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:<xml> 标签标志着一个 文档 的开始,</xml> 标签标志着这个文档的结束。
  • 节点Node:<node> 标签代表了一个 节点。
  • 元素Element:<element>Penguin</element> 中,从开头的 < 到最后的 > 表示了一个 元素。
  • 内容Content: 在 <element> 元素里,字符串 Penguin 就是 内容。

不管你信不信,只要了解了以上几个概念,你就可以开始编写、解析 XML 文件了。

创建一个示例配置文件

学习如何解析 XML 文件,只需要一个极简的示例文件就够了。假设现在有一个配置文件,里面保存的是关于一个图形界面窗口的属性:

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

创建一个名为 ~/.config/DemoXMLParser 的目录:

$ mkdir ~/.config/DemoXMLParser

linux 中,~/.config 目录是存放配置文件的默认位置,这是在 自由桌面工作组 的规范中定义的。如果你正在使用一个不遵守 自由桌面工作组Freedesktop标准的操作系统,你也仍然可以使用这个目录,只不过你需要自己创建这些目录了。

复制 XML 的示例配置文件,粘贴并保存为 ~/.config/DemoXMLParser/myconfig.xml 文件。

使用 Java 解析 XML

如果你是 Java 的初学者,你可以先阅读我写的 面向 Java 入门开发者的 7 个小技巧。一旦你对 Java 比较熟悉了,打开你最喜爱的集成开发工具(IDE),创建一个新工程。我会把我的新工程命名为 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 这两个类来创建一个内部的文档构造器,这样 Java 程序就可以导入并解析 XML 数据了。

最后,Java 创建一个叫 doc 的文档对象,并且把 configFile 文件加载到这个对象里。通过使用 org.w3c.dom 包,它读取并规范化了 XML 数据。

基本上就是这样啦。理论上来讲,你已经完成了数据解析的工作。可是,如果你不能够访问数据的话,数据解析也没有多少用处嘛。所以,就让我们再来写一些查询,从你的配置中读取重要的属性值吧。

使用 Java 访问 XML 的值

从你已经读取的 XML 文档中获取数据,其实就是要先找到一个特定的节点,然后遍历它包含的所有元素。通常我们会使用多个循环语句来遍历节点中的元素,但是为了保持代码可读性,我会尽可能少地使用循环语句:

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 类,创建了一个名为 nodes 的 NodeList 对象。这个对象包含了所有名字匹配字符串 window 的子节点,实际上这样的节点只有一个,因为本文的示例配置文件中只配置了一个。

紧接着,它使用了一个 for 循环来遍历 nodes 列表。具体过程是:根据节点出现的顺序逐个取出,然后交给一个 if-then 子句处理。这个 if-then 子句创建了一个名为 myelement 的 Element 对象,其中包含了当前节点下的所有元素。你可以使用例如 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 的规范格式,然后依靠你用的编程语言的内置功能来处理这些复杂的事情。

这也正是我喜欢使用 Java 和 XML 的原因。每当我试图读取错误的配置值时,Java 就会提醒我。通常,这是由于我在代码中试图获取的节点,并不存在于我期望的 XML 路径中。XML 这种高度结构化的格式帮助了代码保持可靠性,这对用户和开发者来说都是有好处的。

via: https://opensource.com/article/21/7/parsing-config-files-java

以上就是Java持久化XML文件配置解析的详细内容,更多关于Java持久化XML文件配置的资料请关注编程网其它相关文章!

--结束END--

本文标题: Java持久化XML文件配置解析

本文链接: https://www.lsjlt.com/news/143468.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Java持久化XML文件配置解析
    目录前言选择一个格式XML 基础创建一个示例配置文件使用 Java 解析 XML使用 Java 访问 XML 的值使用 Java 更新 XML如何保证配置不出问题前言 当你编写一个应...
    99+
    2022-11-13
  • Java持久化XML文件怎么配置
    今天小编给大家分享一下Java持久化XML文件怎么配置的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。选择一个格式编写配置文件...
    99+
    2023-06-29
  • Redis系列(四)Redis配置文件和持久化
    NoSQL 开发中或多或少都会用到,也是面试必问知识点。最近这几天的面试每一场都问到了。但是感觉回答的并不好,还有很多需要梳理的知识点。这里通过几篇 Redis 笔记整个梳理一遍,后面再加上面试题。 Redis 系列: ...
    99+
    2019-08-17
    Redis系列(四)Redis配置文件和持久化
  • Redis中的配置文件,数据持久化,事务
    目录一、配置文件1、Redis 的网络相关配置2、Redis的常规配置3、Redis的安全配置二、数据持久化1、RDB2、AOF三、事务1、multi2、exec3、discard4...
    99+
    2022-12-22
    Redis配置文件 Redis数据持久化 Redis事务
  • redis中持久化配置的示例分析
    这篇文章主要介绍了redis中持久化配置的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。redis的持久化配置(图文介绍)redis...
    99+
    2022-10-18
  • Java中解析XML文件
    1.初识XML 1.1 定义         XML(EXtensible Markup Language),可扩展标记语言,相比于HTML可以自定义标签,不遵循W3C标准         XML特点:跨平台、跨语言、跨系统。XML与操作系...
    99+
    2023-09-23
    xml
  • SpringCloud-Alibaba-Sentinel-配置持久化策略详解
    前言: Sentinel的如果没有配置持久化的话配置一些 流控 和服务降级 从启项目就会置空所以需要持久化的操作 动态规则扩展 拉模式:客户端主动向某个规则管理中心定期轮询拉取规则...
    99+
    2022-11-11
  • java怎么读取xml配置文件
    在Java中,读取XML配置文件有多种方法,其中比较常用的是使用DOM解析器或者SAX解析器。1. 使用DOM解析器:```java...
    99+
    2023-09-11
    java
  • Java解析XML文件开源库DOM4J
    目录XML解析-DOM4J解析DOM4J查詢DOM4J創建DOM4JXML解析-DOM4J DOM4j是一個開源的,基於java的庫來解析XML文檔,它具有高度的靈活性,高性能和內存...
    99+
    2023-01-11
    Java DOM4J Java解析xml文档
  • Mysql 文件配置解析
    目录client 端配置mysqld 端配置其他设置sql_mode总结前言: mysql数据库在日常工作开发中经常用到的存储设备, 之前已经分享了面试过程中经常被问到的mysql优...
    99+
    2022-11-13
  • Redis配置文件解析
    Redis概述:    是一个基于Key-Value的持久化数据库存储,支持丰富的数据类型,用C语言编写,可基于内存又可持久化的日志型、Key-Value数据库,并提...
    99+
    2022-10-18
  • Java中使用DOM4J生成xml文件并解析xml文件的操作
    目录一、前言二、准备依赖三、生成xml文件生成标准展示四、解析xml文件五、总结一、前言 现在有不少需求,是需要我们解析xml文件中的数据,然后导入到数据库中,当然解析xml文件也有...
    99+
    2022-11-12
  • 一文详解测试Python读写xml配置文件
    前言: xml也是常用的配置文件格式之一,Python中的xml.etree.ElementTree模块支持解析和创建xml数据。xml格式不再赘述,本文采用参考文献1中的示例xml...
    99+
    2022-11-11
  • Java XML文件解析的方法有哪些
    Java中有多种方法可以解析XML文件,其中常用的有以下几种:1. DOM解析器:使用DOM解析器可以将整个XML文档加载到内存中,...
    99+
    2023-09-14
    java
  • Java解析xml文件和json转换的方法(DOM4j解析)
    Java解析xml的方法有四种: DOM解析 SAX解析 JDOM解析 DOM4J解析 本次主要介绍使用DOM4j进行解析: 这里我主要使用两种方...
    99+
    2022-11-12
  • Spring 加载多个xml配置文件的原理分析
    目录示例spring-configlication.xml:spring-config-instance-factory.xmljava示例代码实现AbstractRefreshab...
    99+
    2022-11-12
  • mysql配置文件my-small.cnf解析,汉文翻译,配置
    # Example MySQL config file for small systems.#数据库最小系统配置文件样例# T...
    99+
    2022-10-18
  • 全面解析SpringBoot配置文件
    目录1.文件类型1.1properties1.2yaml简介基本语法数据类型举例2.配置提示1.文件类型 1.1properties 同以前的properties用法。 1.2yam...
    99+
    2022-11-12
  • 利用java怎么对xml文件进行解析
    利用java怎么对xml文件进行解析?相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。一、【基础知识——扫盲】sax、dom是两种对xml文档进行解析的方法(没有具体实现,只是接口...
    99+
    2023-05-31
    java xml ava
  • 一文详解Spring是怎么读取配置Xml文件的
    目录Spring读取配置文件DocumentElementDocumentDefaultsDefinitionSpring读取配置文件Document 在XmlBeanDefinit...
    99+
    2022-11-13
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作