Java与XML交互:读取与解析实战
在编程中,我们常常需要存储具有特定结构的信息,并且希望这些信息在一定程度上是人类可读的,甚至可以由人工编辑。XML(可扩展标记语言)就是这样一种强大的工具,它能够很好地满足这些需求。Java为我们提供了丰富的工具来处理XML数据,包括读取、解析和修改等操作。接下来,我们将详细介绍如何使用Java来完成这些任务。
读取XML数据
我们将以
cars.xml
文件为例,学习如何使用Java将XML文件加载到Java对象中。首先,确保
cars.xml
文件存储在Java项目的当前目录下,这样在运行Java程序时就可以直接访问该文件。
以下是用于加载
cars.xml
文件的Java程序:
package loadinganxmlfile;
import java.io.*;
import javax.xml.parsers.*;
import javax.xml.transform.*;
import javax.xml.transform.dom.*;
import javax.xml.transform.stream.*;
import org.w3c.dom.*;
import org.xml.sax.*;
public class LoadingAnXMLFile {
public static void main(String[] args) {
try {
//Write code that can throw errors here
}
catch (ParserConfigurationException pce) {
System.out.println(pce.getMessage());
}
catch (SAXException se) {
System.out.println(se.getMessage());
}
catch (IOException ioe) {
System.err.println(ioe.getMessage());
}
}
private static void PrintXmlDocument(Document xml)
{
try{
Transformer transformer =
TransformerFactory.newInstance().newTransformer();
StreamResult result = new StreamResult
(new StringWriter());
DOMSource source = new DOMSource(xml);
transformer.transform(source, result);
System.out.println(result.getWriter().toString());
}
catch(TransformerConfigurationException e)
{
System.err.println("XML Printing Failed");
}
catch(TransformerException e)
{
System.err.println("XML Printing Failed");
}
}
}
在开始编写代码之前,需要注意该程序需要导入大量的库。其中,
transform
类虽然在后续代码中并非必需,但我编写了一个名为
PrintXmlDocument()
的函数,用于在成功加载XML文档后将其打印到控制台。
接下来,我们的目标是创建一个
Document
对象,该对象包含
cars.xml
文件中的信息。创建
Document
对象的步骤如下:
1.
实例化
DocumentBuilderFactory
:使用
DocumentBuilderFactory
类的静态方法
newInstance()
来创建一个
DocumentBuilderFactory
实例。
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
-
获取
DocumentBuilder对象 :调用factory的newDocumentBuilder()方法来获取一个DocumentBuilder对象。
DocumentBuilder builder = factory.newDocumentBuilder();
-
构建
Document对象 :使用builder的parse()方法来解析cars.xml文件,并将结果存储在Document对象中。
Document dom = builder.parse("cars.xml");
最终,
main()
方法的代码如下:
public static void main(String[] args) {
DocumentBuilderFactory factory =
DocumentBuilderFactory.newInstance();
try {
// Write code that can throw errors here...
DocumentBuilder builder =
factory.newDocumentBuilder();
Document dom = builder.parse("cars.xml");
PrintXmlDocument(dom);
}
catch (ParserConfigurationException pce) {
System.out.println(pce.getMessage());
}
catch (SAXException se) {
System.out.println(se.getMessage());
}
catch (IOException ioe) {
System.err.println(ioe.getMessage());
}
}
运行该程序后,我们将得到原始XML文档的文本输出。
解析XML数据
接下来,我们将学习如何解析XML数据。
cars.xml
文件的内容如下:
<?xml version="1.0"?>
<cars>
<owner name="Billy">
<car vin="LJPCBLCX11000237">
<make>Ford</make>
<model>Fusion</model>
<year>2014</year>
<color>Blue</color>
</car>
<car vin="LGHIALCX89880011">
<make>Toyota</make>
<model>Tacoma</model>
<year>2013</year>
<color>Green</color>
</car>
<car vin="GJSIALSS22000567">
<make>Dodge</make>
<model>Charger</model>
<year>2013</year>
<color>Red</color>
</car>
</owner>
<owner name="Jane">
<car vin="LLOKAJSS55548563">
<make>Nissan</make>
<model>Altima</model>
<year>2000</year>
<color>Green</color>
</car>
<car vin="OOKINAFS98111001">
<make>Dodge</make>
<model>Challenger</model>
<year>2013</year>
<color>Red</color>
</car>
</owner>
</cars>
该文件的根节点是
cars
,其中包含两个
owner
节点(
Billy
和
Jane
),每个
owner
节点下又包含多个
car
节点。
我们的目标是提取
Jane
所拥有的汽车信息,并将其存储在自定义的
Car
类中,以便使用
Car
类的
toString()
方法将这些信息以格式化的方式打印到控制台。
在解析XML数据之前,我们需要了解一些XML术语。在XML中,
element
是具有开始和结束标签的实体,包含其中的所有信息;
node
是XML文档的构建块,所有的
element
都是
node
,但并非所有的
node
都是
element
。
访问
Jane
的XML元素
为了访问
Jane
的汽车信息,我们需要在
main()
函数中添加以下代码:
1.
获取根元素
:使用
dom
的
getDocumentElement()
方法获取XML文档的根元素。
Element doc = dom.getDocumentElement();
-
获取所有
owner节点 :调用根元素的getElementsByTagName()方法,获取所有owner元素,并将结果存储在NodeList对象中。
NodeList ownersList = doc.getElementsByTagName("owner");
-
遍历
owner节点 :遍历ownersList,检查每个owner节点的name属性是否为Jane。
for(int i = 0; i < ownersList.getLength(); i++)
{
Element owner = (Element)ownersList.item(i);
if(owner.getAttribute("name").equals("Jane"))
{
NodeList carsList = owner.getElementsByTagName("car");
PrintCars(carsList);
}
}
此时,
main()
方法的代码如下:
public static void main(String[] args) {
DocumentBuilderFactory factory =
DocumentBuilderFactory.newInstance();
try {
DocumentBuilder docBuilder =
factory.newDocumentBuilder();
Document dom = docBuilder.parse("cars.xml");
// Now, print out all of Jane's cars
Element doc = dom.getDocumentElement();
NodeList ownersList =
doc.getElementsByTagName("owner");
for(int i = 0; i < ownersList.getLength(); i++)
{
Element owner = (Element)ownersList.item(i);
if(owner.getAttribute("name").equals("Jane"))
{
NodeList carsList =
owner.getElementsByTagName("car");
PrintCars(carsList);
}
}
}
catch (ParserConfigurationException pce) {
System.out.println(pce.getMessage());
}
catch (SAXException se) {
System.out.println(se.getMessage());
}
catch (IOException ioe) {
System.err.println(ioe.getMessage());
}
}
打印
Jane
的汽车详细信息
接下来,我们需要定义
PrintCars()
方法,用于打印
Jane
的汽车详细信息。该方法的定义如下:
public static void PrintCars(NodeList cars)
{
for(int i = 0; i < cars.getLength(); i++)
{
Element carNode = (Element)cars.item(i);
Car carObj = new Car();
carObj.color = carNode.getElementsByTagName("color").item(0).getTextContent();
carObj.make = carNode.getElementsByTagName("make").item(0).getTextContent();
carObj.model = carNode.getElementsByTagName("model").item(0).getTextContent();
carObj.year = Integer.parseInt(carNode.getElementsByTagName("year").item(0).getTextContent());
carObj.vin = carNode.getAttribute("vin");
System.out.println(carObj.toString());
}
}
该方法的具体步骤如下:
1.
遍历
cars
列表
:使用
for
循环遍历
cars
列表中的每个
car
节点。
2.
创建
Car
对象
:为每个
car
节点创建一个
Car
对象。
3.
提取汽车信息
:使用
getElementsByTagName()
方法提取
color
、
make
、
model
和
year
信息,并使用
getAttribute()
方法提取
vin
信息。
4.
打印汽车信息
:调用
Car
对象的
toString()
方法,将汽车信息以格式化的方式打印到控制台。
以下是
Car
类的定义:
package readingxml;
public class Car {
public String vin;
public String make;
public String model;
public int year;
public String color;
public Car()
{
}
@Override
public String toString()
{
return String.format("%d %s %s %s, vin:%s", year,
color, make, model, vin);
}
}
编译并运行该程序,我们将看到
Jane
所拥有的汽车信息以格式化的方式打印到控制台。
整个读取和解析XML数据的流程可以用以下mermaid流程图表示:
graph TD;
A[开始] --> B[实例化DocumentBuilderFactory];
B --> C[获取DocumentBuilder对象];
C --> D[构建Document对象];
D --> E[获取根元素];
E --> F[获取所有owner节点];
F --> G[遍历owner节点];
G --> H{是否为Jane};
H -- 是 --> I[获取Jane的car节点];
I --> J[打印Jane的汽车信息];
H -- 否 --> G;
J --> K[结束];
通过以上步骤,我们成功地使用Java读取和解析了XML数据。XML和Java的结合非常强大,XML不仅人类可读,还包含了有价值的结构化信息,而Java能够很好地理解和处理这些信息。与处理原始文本文件相比,使用XML和Java编写的程序更加易于编写、理解和维护。
Java与XML交互:读取与解析实战
总结与注意事项
在整个使用 Java 读取和解析 XML 数据的过程中,有一些关键要点和注意事项需要我们牢记:
关键要点
-
库的导入
:在编写 Java 程序处理 XML 时,需要导入大量的库,如
javax.xml.parsers.*、javax.xml.transform.*等。虽然有些库在某些代码中并非必需,但为了后续可能的功能扩展和代码的完整性,建议提前导入。 -
对象的创建
:创建
Document对象需要通过DocumentBuilderFactory和DocumentBuilder来完成,不能直接实例化。这是为了确保 XML 文件的可解析性和数据结构的正确性。 -
XML 术语的理解
:在解析 XML 数据时,要清楚
element和node的区别。element是具有开始和结束标签的实体,包含其中的所有信息;node是 XML 文档的构建块,所有的element都是node,但并非所有的node都是element。
注意事项
-
异常处理
:在编写代码时,要注意对可能出现的异常进行处理,如
ParserConfigurationException、SAXException和IOException等。通过捕获这些异常并进行相应的处理,可以提高程序的健壮性。 - XML 格式的正确性 :在解析 XML 数据时,假设 XML 文件的格式是正确的。如果 XML 文件格式不正确,可能会导致程序出现异常或解析结果不准确。因此,在实际应用中,建议对 XML 文件进行有效性检查。
扩展应用
除了上述的读取和解析 XML 数据的基本操作,我们还可以进行一些扩展应用,如修改和写入 XML 数据。
修改 XML 数据
假设我们要修改
Jane
的某一辆汽车的信息,例如将
vin="LLOKAJSS55548563"
的汽车颜色改为
Yellow
。可以按照以下步骤进行:
1.
定位要修改的节点
:在
PrintCars()
方法中,找到对应的
carNode
。
2.
修改节点信息
:使用
carNode.getElementsByTagName("color").item(0).setTextContent("Yellow")
方法修改颜色信息。
3.
保存修改后的 XML 文件
:使用
Transformer
类将修改后的
Document
对象保存到文件中。
以下是修改后的
PrintCars()
方法和保存 XML 文件的代码示例:
public static void PrintCars(NodeList cars)
{
for(int i = 0; i < cars.getLength(); i++)
{
Element carNode = (Element)cars.item(i);
if (carNode.getAttribute("vin").equals("LLOKAJSS55548563")) {
carNode.getElementsByTagName("color").item(0).setTextContent("Yellow");
}
Car carObj = new Car();
carObj.color = carNode.getElementsByTagName("color").item(0).getTextContent();
carObj.make = carNode.getElementsByTagName("make").item(0).getTextContent();
carObj.model = carNode.getElementsByTagName("model").item(0).getTextContent();
carObj.year = Integer.parseInt(carNode.getElementsByTagName("year").item(0).getTextContent());
carObj.vin = carNode.getAttribute("vin");
System.out.println(carObj.toString());
}
try {
Transformer transformer = TransformerFactory.newInstance().newTransformer();
DOMSource source = new DOMSource(dom);
StreamResult result = new StreamResult(new File("modified_cars.xml"));
transformer.transform(source, result);
} catch (TransformerConfigurationException e) {
System.err.println("XML Saving Failed");
} catch (TransformerException e) {
System.err.println("XML Saving Failed");
}
}
写入 XML 数据
如果我们要创建一个新的 XML 文件,可以按照以下步骤进行:
1.
创建
Document
对象
:使用
DocumentBuilderFactory
和
DocumentBuilder
创建一个新的
Document
对象。
2.
创建 XML 元素
:使用
Document
对象的
createElement()
方法创建 XML 元素,并使用
appendChild()
方法将元素添加到父元素中。
3.
设置元素属性和文本内容
:使用
setAttribute()
方法设置元素的属性,使用
setTextContent()
方法设置元素的文本内容。
4.
保存 XML 文件
:使用
Transformer
类将
Document
对象保存到文件中。
以下是创建新 XML 文件的代码示例:
import java.io.File;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Transformer;
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;
public class WriteXML {
public static void main(String[] args) {
try {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.newDocument();
// 创建根元素
Element root = doc.createElement("cars");
doc.appendChild(root);
// 创建 owner 元素
Element owner = doc.createElement("owner");
owner.setAttribute("name", "NewOwner");
root.appendChild(owner);
// 创建 car 元素
Element car = doc.createElement("car");
car.setAttribute("vin", "NEWVIN123");
owner.appendChild(car);
// 创建 make、model、year 和 color 元素
Element make = doc.createElement("make");
make.setTextContent("NewMake");
car.appendChild(make);
Element model = doc.createElement("model");
model.setTextContent("NewModel");
car.appendChild(model);
Element year = doc.createElement("year");
year.setTextContent("2024");
car.appendChild(year);
Element color = doc.createElement("color");
color.setTextContent("NewColor");
car.appendChild(color);
// 保存 XML 文件
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
DOMSource source = new DOMSource(doc);
StreamResult result = new StreamResult(new File("new_cars.xml"));
transformer.transform(source, result);
System.out.println("XML file created successfully.");
} catch (Exception e) {
e.printStackTrace();
}
}
}
总结
通过本文的介绍,我们学习了如何使用 Java 读取、解析、修改和写入 XML 数据。XML 和 Java 的结合为我们处理结构化数据提供了强大的工具。在实际应用中,我们可以根据具体需求灵活运用这些技术,实现各种功能。
以下是一个总结表格,对比了读取、解析、修改和写入 XML 数据的操作步骤:
| 操作类型 | 操作步骤 |
| ---- | ---- |
| 读取 XML 数据 | 1. 实例化
DocumentBuilderFactory
;2. 获取
DocumentBuilder
对象;3. 构建
Document
对象 |
| 解析 XML 数据 | 1. 获取根元素;2. 获取所有
owner
节点;3. 遍历
owner
节点,找到目标节点;4. 提取节点信息 |
| 修改 XML 数据 | 1. 定位要修改的节点;2. 修改节点信息;3. 保存修改后的 XML 文件 |
| 写入 XML 数据 | 1. 创建
Document
对象;2. 创建 XML 元素;3. 设置元素属性和文本内容;4. 保存 XML 文件 |
希望本文对你理解和应用 Java 与 XML 的交互有所帮助,让你在处理结构化数据时更加得心应手。
超级会员免费看
1626

被折叠的 条评论
为什么被折叠?



