>  기사  >  Java  >  Java 지속성 XML 파일을 구성하는 방법

Java 지속성 XML 파일을 구성하는 방법

WBOY
WBOY앞으로
2023-05-04 09:40:06868검색

형식 선택

구성 파일을 작성하는 것은 다소 복잡한 일입니다. 구성 항목을 쉼표로 구분된 텍스트 파일에 저장해 보았고 매우 자세한 YAML 및 XML로 구성 항목을 저장해 보았습니다. 구성 파일의 경우 가장 중요한 것은 일관성과 규칙성을 갖는 것입니다. 이를 통해 쉽고 빠르게 코드를 작성하고 동시에 구성 파일의 데이터를 구문 분석할 수 있으며, 사용자가 변경하기로 결정하면 저장하기가 쉽습니다. 구성을 업데이트합니다.

현재 널리 사용되는 구성 파일 형식은 여러 가지가 있습니다. 가장 일반적인 구성 파일 형식에 대해 Java에는 해당 라이브러리가 있습니다. 이 글에서는 XML 형식을 사용하겠습니다. 일부 프로젝트에서는 뛰어난 기능 중 하나가 포함된 데이터에 대한 풍부한 관련 메타데이터를 제공하는 기능 때문에 XML을 사용하도록 선택할 수 있지만, 다른 프로젝트에서는 XML의 장황함 때문에 XML을 선택하지 않을 수도 있습니다. Java에서 XML 작업은 기본적으로 강력한 XML 라이브러리가 많이 포함되어 있기 때문에 매우 쉽습니다.

XML 기초

XML을 논의하는 것은 큰 주제입니다. 나는 700페이지가 넘는 XML에 관한 책을 가지고 있습니다. 다행히도 XML 작업에는 XML의 많은 기능에 대한 깊은 지식이 필요하지 않습니다. HTML과 마찬가지로 XML은 여는 태그와 닫는 태그가 있는 계층화된 마크업 언어이며, 각 태그에는 0개 이상의 데이터가 포함될 수 있습니다. 다음은 XML의 간단한 예제 조각입니다.

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

이 자체 설명적 예제에서 XML 파서는 다음 개념을 사용합니다.

  • Document Document: b2a0af5a8fd26276da50279a1c63a57a 태그는 시작을 표시합니다. 문서의 끝을 표시하며 21118965b89073f60271ef4a3b5d3c58 태그는 문서의 끝을 표시합니다. b2a0af5a8fd26276da50279a1c63a57a 标签标志着一个 文档 的开始,21118965b89073f60271ef4a3b5d3c58 标签标志着这个文档的结束。

  • 节点Node:37493a7a244a2c0740719da11c0bbc72 标签代表了一个 节点。

  • 元素Element:1dd643d91c792abd0a34d1b312e2f207Penguina24c0203f0ae689239f065103120aae7 中,从开头的 068bb6aff869d1ddc703642984eade01 表示了一个 元素。

  • 内容Content: 在 1dd643d91c792abd0a34d1b312e2f207 元素里,字符串 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

노드: 37493a7a244a2c0740719da11c0bbc72 라벨은 노드를 나타냅니다.

🎜🎜요소: 1dd643d91c792abd0a34d1b312e2f207Penguina24c0203f0ae689239f065103120aae7, 처음 28c5a459082e6574b9af2d608e2add9e code>까지 요소를 나타냅니다. 🎜🎜🎜콘텐츠: <code>1dd643d91c792abd0a34d1b312e2f207 요소에서 Penguin 문자열이 콘텐츠입니다. 🎜🎜믿거나 말거나 위의 개념을 이해했다면 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());
 }
}
🎜 ~/.config/DemoXMLParser라는 디렉터리를 만듭니다. 🎜
$ java ./DemoXMLParser.java
Property = window
Theme = Dark
Fullscreen = 0
Icon set = Tango
🎜Linux에서는 ~/. config 디렉토리는 Free Desktop Working Group의 사양에 정의된 대로 구성 파일의 기본 위치입니다. Freedesktop 표준을 준수하지 않는 운영 체제를 사용하는 경우에도 이 디렉터리를 사용할 수 있지만 이러한 디렉터리를 직접 만들어야 합니다. 🎜🎜XML 샘플 구성 파일을 복사하여 붙여넣고 ~/.config/DemoXMLParser/myconfig.xml 파일로 저장합니다. 🎜🎜Java를 사용하여 XML 구문 분석🎜🎜Java 초보자라면 먼저 초보 Java 개발자를 위한 7가지 팁을 읽어보세요. Java에 익숙해지면 즐겨 사용하는 IDE(통합 개발 도구)를 열고 새 프로젝트를 만드세요. 새 프로젝트의 이름을 myConfigParser로 지정하겠습니다. 🎜🎜처음에는 종속성 가져오기 및 예외 포착에 너무 많은 주의를 기울이지 마세요. 먼저 javaxjava.io에서 표준 Java 확장을 사용해 볼 수 있습니다. 파서 장치를 인스턴스화하는 패키지입니다. IDE를 사용하는 경우 적절한 종속성을 가져오라는 메시지가 표시됩니다. 그렇지 않은 경우 기사 뒷부분에서 전체 종속성 목록이 포함된 전체 코드를 찾을 수 있습니다. 🎜
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.nio.Paths 클래스를 사용하여 사용자의 홈 디렉터리를 찾은 다음 경로를 기본 구성 파일에 연결합니다. 다음으로 java.io.File 클래스를 사용하여 구성 파일을 File 객체로 정의합니다. 🎜🎜다음으로 javax.xml.parsers.DocumentBuilderjavax.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 这种高度结构化的格式帮助了代码保持可靠性,这对用户和开发者来说都是有好处的。

위 내용은 Java 지속성 XML 파일을 구성하는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 yisu.com에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제