【常见配置文件】XML文件(Java)

519 阅读9分钟

XML文件

在学习XML之前,先了解:为什么需要配置文件

配置文件是一种用于保存应用程序配置信息的文件,它可以包含各种设置和参数,例如数据库连接信息、应用程序行为、用户界面布局等。以下是一些需要使用配置文件的原因:

  1. 简化应用程序配置:应用程序需要许多参数和设置,这些参数和设置可能会因环境变化而变化。使用配置文件可以将这些参数和设置集中到一个文件中,并且可以在运行时轻松修改。
  2. 提高应用程序可维护性:将应用程序配置信息保存到配置文件中,可以使应用程序更易于维护。如果需要更改某些配置信息,只需修改配置文件,而不需要修改应用程序代码
  3. 提高应用程序的可移植性:应用程序需要在不同的环境中运行,例如开发环境、测试环境和生产环境。使用配置文件可以使应用程序更易于移植,因为可以根据不同的环境配置不同的参数和设置。
  4. 增加应用程序的可扩展性:应用程序需要不断进行更新和改进,使用配置文件可以使应用程序更易于扩展。新功能和参数可以添加到配置文件中,而不需要修改应用程序代码。

XML文件定义

XML(eXtensible Markup Language)是一种通用的标记语言,用于描述数据结构和内容。它可以用来表示各种类型的数据,包括文本、数字、日期、图形、音频和视频等。

XML 文件由标签和标签内容组成,每个标签用尖括号括起来,例如 <book> 和 </book>,其中第一个标签是开始标签,第二个标签是结束标签。开始标签和结束标签之间的内容是标签内容,可以是文本、其他标签、属性等。

XML 文件具有以下特点

  1. 可扩展性:XML 文件可以使用自定义标签和属性(html只能特定标签),使其更适合特定的应用领域。
  2. 可读性:XML 文件使用了通用的标记语言,易于阅读、编写和理解
  3. 可解析性:XML 文件可以通过解析器进行解析和处理,以便将数据提取到其他应用程序中。
  4. 平台无关性:XML 文件可以在任何平台上使用,因为它是纯文本格式

从XML的编写形式可以看出来,它非常适合结构化的文件 一是纯文本,默认使用UTF-8编码,二是可嵌套,适合表示结构化数据。

XML文件的内容结构

XML(可扩展标记语言)是一种用于表示数据的标记语言,其结构由以下几个部分组成:

  1. XML声明:XML文档必须以XML声明作为开头,以指示文档使用的XML版本和编码方式。示例:<?xml version="1.0" encoding="UTF-8"?>
  2. 根元素:XML文档必须有一个根元素,所有其他元素都是它的子元素。根元素需要使用开始标记和结束标记包围内容。示例:<root>...</root>
  3. 元素:XML文档中的元素用起始标记和结束标记来定义,起始标记包含元素名称,结束标记用斜杠和元素名称表示。元素可以包含属性和子元素。示例:<element attribute="value">...</element>
  4. 属性:元素可以包含属性,用来提供有关元素的额外信息。属性由名称和值组成,用等号连接。示例:<element attribute="value">...</element>
  5. 注释:XML文档可以包含注释,用于提供关于文档内容的说明。注释以<!--开头,以-->结尾。示例:<!-- This is a comment -->
  6. CDATA节:CDATA节用于包含文本数据,这些数据可能包含XML特殊字符(如<&),这些字符需要保留在数据中。CDATA节以<![CDATA[开头,以]]>结尾。示例:<![CDATA[<p>This is some text</p>]]>

简单示例:

<?xml version="1.0" encoding="UTF-8"?>
<root>
  <person name="John" age="30">
    <address>
      <street>123 Main St</street>
      <city>Anytown</city>
      <state>CA</state>
    </address>
  </person>
  <!-- Another person -->
  <person name="Jane" age="25">
    <address>
      <street>456 Oak Ave</street>
      <city>Someville</city>
      <state>NY</state>
    </address>
  </person>
</root>

XML文件的结构可以表示为树形结构

image.png

要表示特殊字符怎么办

比如大于> ,小于<, 及引号。如果内容出现了特殊符号,需要使用&???;表示转义。

常见字符: image.png

XML文件的写法特点

  1. HTML 会把多个连续的空格字符裁减(合并)为一个:
HTML:	Hello           my name is David.
输出:	Hello my name is David.

2. XML 属性必须加引号

属性值必须被引号包围,不过单引号和双引号均可使用。比如一个人的性别,person 标签可以这样写:

<person sex="female">
<person sex='female'>

3. 没有什么规矩可以告诉我们什么时候该使用属性,而什么时候该使用子元素。我的经验是在 HTML 中,属性用起来很便利,但是在 XML 中,您应该尽量避免使用属性(便于读取)。如果信息感觉起来很像数据,那么请使用子元素吧。

<person sex="female">
  <firstname>Anna</firstname>
  <lastname>Smith</lastname>
</person> 

<person>
  <sex>female</sex>
  <firstname>Anna</firstname>
  <lastname>Smith</lastname>
</person> 

在第一个例子中,sex 是一个属性。在第二个例子中,sex 则是一个子元素。两个例子均可提供相同的信息。

  1. 为什么要避免 XML 属性?

因使用属性而引起的一些问题:

  • 属性无法包含多重的值(元素可以)
  • 属性无法描述树结构(元素可以)
  • 属性不易扩展(为未来的变化)
  • 属性难以阅读和维护

请尽量使用元素来描述数据。而仅仅使用属性来提供与数据无关的信息。

  1. 针对元数据的 XML 属性

有时候会向元素分配 ID 引用。这些 ID 索引可用于标识 XML 元素,它起作用的方式与 HTML 中 ID 属性是一样的。这个例子向我们演示了这种情况:

<messages>
  <note id="501">
    <to>George</to>
    <from>John</from>
    <heading>Reminder</heading>
    <body>Don't forget the meeting!</body>
  </note>
  <note id="502">
    <to>John</to>
    <from>George</from>
    <heading>Re: Reminder</heading>
    <body>I will not</body>
  </note> 
</messages>

上面的 ID 仅仅是一个标识符,用于标识不同的便签。它并不是便签数据的组成部分。

在此我们极力向您传递的理念是:元数据(有关数据的数据)应当存储为属性,而数据本身应当存储为元素。

当你想要验证XML文件编写是否正确,可以到在线网站检查

XML文件在浏览器的显示

  • 显示成功: 显示为源代码,因为浏览器不可能像读取HTML那样去读取XML文件。
  • 显示失败:网站显示Error

差不多了解XML文件后, 使用Java去操作XML文件。

Java读取XML文件

DOM 把 XML 文档视为一种树结构。通过这个 DOM 树,可以访问所有的元素。可以修改它们的内容(文本以及属性),而且可以创建新的元素。元素,以及它们的文本和属性,均被视为节点。

  1. 创建一个DocumentBuilderFactory对象来获取DocumentBuilder对象。
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
// 这里可以进行builder的个性化设置,调用类里的方法

2. 使用DocumentBuilder对象的parse()方法将XML文件解析为Document对象。

Document doc = builder.parse(new File("example.xml"));

3. 获取XML文件的根元素。

Element root = doc.getDocumentElement();

4. 遍历XML文件中的元素,并获取元素的属性和子元素。

//根据标签名去获取元素结点,默认返回一个列表
NodeList bookList = root.getElementsByTagName("book");
for (int i = 0; i < bookList.getLength(); i++) {
    Element book = (Element) bookList.item(i);
    // 获得book标签的id属性
    String id = book.getAttribute("id");
    // 获取book元素的属性
    // `getTextContent()`方法可以返回指定节点及其子节点的文本内容,而`getNodeValue()`方法只能返回指定节点的值(即节点本身的值),不包括其子节点的值。
    String author = book.getElementsByTagName("author").item(0).getTextContent();
    String title = book.getElementsByTagName("title").item(0).getTextContent();
    String genre = book.getElementsByTagName("genre").item(0).getTextContent();
    double price = Double.parseDouble(book.getElementsByTagName("price").item(0).getTextContent());
    String publishDate = book.getElementsByTagName("publish_date").item(0).getTextContent();
    String description = book.getElementsByTagName("description").item(0).getTextContent();
    // do something with the book information...
}

知识点补充:

为什么要使用DocumentBuilderFactory 使用DocumentBuilderFactory可以灵活地配置和定制DocumentBuilder对象的特性,例如是否对文档进行验证、是否忽略注释等等。这些特性可以通过调用DocumentBuilderFactory的方法来设置,然后通过DocumentBuilderFactory创建的DocumentBuilder对象来应用。

另外,使用DocumentBuilderFactory还可以提高应用程序的性能和安全性。由于DocumentBuilderFactory是线程安全的,因此可以在多个线程中共享一个实例,从而避免了创建多个DocumentBuilder对象的开销。此外,DocumentBuilderFactory还允许应用程序限制可以使用的外部实体和脚本,从而提高了应用程序的安全性。

综上所述,使用DocumentBuilderFactory来获取DocumentBuilder对象可以提高代码的灵活性、可维护性、可重用性和性能。

可以使用DocumentBuilderFactory对象的方法来配置和定制DocumentBuilder的特性,以下是一些常用的方法:

  1. setValidating(boolean validating):设置是否启用验证,默认值为false
  2. setIgnoringElementContentWhitespace(boolean whitespace):设置是否忽略元素内容中的空格,默认值为false
  3. setIgnoringComments(boolean ignoreComments):设置是否忽略注释,默认值为false
  4. setCoalescing(boolean coalescing):设置是否将CDATA节点转换为文本节点,默认值为false
  5. setNamespaceAware(boolean awareness):设置是否启用命名空间处理,默认值为false
  6. setExpandEntityReferences(boolean expandEntityReferences):设置是否扩展实体引用,默认值为true

Java修改XML文件

// 加载XML文档
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parse(new File("example.xml"));

// 获取需要修改的元素节点
NodeList nodeList = doc.getElementsByTagName("title");
Element titleElement = (Element)nodeList.item(0);

// 修改元素的内容
titleElement.setTextContent("The New Title");

// 保存修改后的XML文档
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
DOMSource source = new DOMSource(doc);
StreamResult result = new StreamResult(new File("example.xml"));
transformer.transform(source, result);

知识点补充

TransformerFactory是一个用于创建Transformer对象的工厂类,它提供了创建和配置Transformer对象的方法。Transformer对象是Java中用于将XML文档转换为其他格式(如HTML、文本、JSON等)或将其他格式转换为XML文档的核心类。

TransformerFactory对象的主要作用包括:

  1. 创建Transformer对象:通过调用TransformerFactory对象的newTransformer()方法,可以创建一个新的Transformer对象。Transformer对象是用于将XML文档转换为其他格式的核心类,它提供了将XML文档转换为字符串、文件、字节流等的方法。
  2. 配置Transformer对象:通过调用TransformerFactory对象的setFeature()方法和setAttribute()方法,可以对Transformer对象进行配置。例如,可以设置Transformer对象的输出编码、缩进方式、DOCTYPE声明等。
  3. 控制Transformer对象的行为:通过调用TransformerFactory对象的setURIResolver()方法和setErrorListener()方法,可以设置Transformer对象的URI解析器和错误处理器,以控制Transformer对象的行为。

以上就是XML文件在Java中的操作了。