前言: XML(可扩展标记语言)和 JSON(JavaScript 对象表示法)是两种常见的数据格式,广泛应用于数据存储、交换和传输等领域。

目录

一、初窥门径

XML 与 JSON 的基础认知

XML —— 结构严谨的 “老大哥”

JSON —— 轻量灵活的 “新宠”

二、实战演练

Java 中的 XML 处理技巧

DOM 解析 —— 将 XML 文档尽收眼底

SAX 解析 —— 逐字细读大型文档

生成 XML —— 创建你的数据文档

三、大显身手

Java 中的 JSON 处理秘籍

Gson 库 —— 简单易用的 JSON 处理利器

Jackson 库 —— 功能强大的 JSON 处理专家

四、进阶之路

XML 与 JSON 的相互转换

XML 转换为 JSON —— 跨越数据格式的桥梁

JSON 转换为 XML —— 反向转换的魔法

五、化繁为简

选择合适的数据处理方式

总结


一、初窥门径

XML 与 JSON 的基础认知

XML —— 结构严谨的 “老大哥”

XML 以其严谨的结构著称,它通过自定义标签来描述数据,使数据具有明确的语义和层次关系。例如,在一个图书馆系统中,我们可以用 XML 来表示书籍信息:

<library>
    <book id="001">
        <title>Java 编程思想</title>
        <author>Bruce Eckel</author>
        <year>2021</year>
    </book>
    <book id="002">
        <title>数据结构与算法分析</title>
        <author>Mark Allen Weiss</author>
        <year>2022</year>
    </book>
</library>

在这个例子中,<library> 是根元素,包含了多个 <book> 元素。每个 <book> 元素都有一个属性 id,以及子元素 <title><author><year>,清晰地描述了每本书的详细信息。

JSON —— 轻量灵活的 “新宠”

JSON 则以简洁、轻量的特点受到开发者的青睐,它采用键值对的形式表示数据,易于阅读和编写,也便于机器解析和生成。例如,上述图书馆系统的书籍信息用 JSON 表示可以是:

{
    "library": {
        "books": [
            {
                "id": "001",
                "title": "Java 编程思想",
                "author": "Bruce Eckel",
                "year": 2021
            },
            {
                "id": "002",
                "title": "数据结构与算法分析",
                "author": "Mark Allen Weiss",
                "year": 2022
            }
        ]
    }
}

在这里,library 是一个对象,包含一个 books 数组,数组中的每个元素都是一个表示书籍信息的对象,直观地展现了数据的层次结构。

二、实战演练

Java 中的 XML 处理技巧

DOM 解析 —— 将 XML 文档尽收眼底

DOM(文档对象模型)解析方式会将整个 XML 文档加载到内存中,构建一个树形结构的对象模型,方便我们对文档进行读取、修改等操作。这种方式对于小型 XML 文档非常适用,能让我们快速获取和更新文档中的数据。下面是一个使用 DOM 解析上述 library.xml 文件的示例:

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.File;

public class XMLDomParserExample {
    public static void main(String[] args) {
        try {
            // 创建 DocumentBuilderFactory 对象
            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
            // 创建 DocumentBuilder 对象
            DocumentBuilder builder = factory.newDocumentBuilder();
            // 加载并解析 XML 文件,得到 Document 对象
            Document document = builder.parse(new File("library.xml"));
            // 规范化文档
            document.getDocumentElement().normalize();
            // 打印根元素名称
            System.out.println("根元素名称: " + document.getDocumentElement().getNodeName());
            // 获取所有 book 元素
            NodeList bookList = document.getElementsByTagName("book");
            // 遍历 book 元素
            for (int i = 0; i < bookList.getLength(); i++) {
                // 获取 book 元素
                Element bookElement = (Element) bookList.item(i);
                // 打印书籍 ID
                System.out.println("书籍 ID: " + bookElement.getAttribute("id"));
                // 获取 title 元素并打印其内容
                System.out.println("书名: " + bookElement.getElementsByTagName("title").item(0).getTextContent());
                // 获取 author 元素并打印其内容
                System.out.println("作者: " + bookElement.getElementsByTagName("author").item(0).getTextContent());
                // 获取 year 元素并打印其内容
                System.out.println("出版年份: " + bookElement.getElementsByTagName("year").item(0).getTextContent());
                // 打印分隔线
                System.out.println("----------------------------");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

运行这段代码,你将看到如下输出:

根元素名称: library
书籍 ID: 001
书名: Java 编程思想
作者: Bruce Eckel
出版年份: 2021
----------------------------
书籍 ID: 002
书名: 数据结构与算法分析
作者: Mark Allen Weiss
出版年份: 2022
----------------------------

SAX 解析 —— 逐字细读大型文档

SAX(简单 API 用于 XML)解析方式采用事件驱动模式,它在解析 XML 文档时会依次触发各种事件,如遇到开始标签、结束标签、文本内容等。这种方式不会将整个文档加载到内存,非常适合处理大型 XML 文件。下面是一个使用 SAX 解析 library.xml 文件的示例:

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import java.io.File;

public class XMLSaxParserExample {
    public static void main(String[] args) {
        try {
            // 创建 SAXParserFactory 对象
            SAXParserFactory factory = SAXParserFactory.newInstance();
            // 创建 SAXParser 对象
            SAXParser parser = factory.newSAXParser();
            // 创建 DefaultHandler 子类对象,用于处理解析事件
            parser.parse(new File("library.xml"), new BookHandler());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    // 定义处理解析事件的类
    static class BookHandler extends DefaultHandler {
        // 用于标记当前正在处理的元素
        private String currentElement = "";
        // 用于存储书籍信息
        private StringBuilder bookInfo = new StringBuilder();

        // 当遇到开始标签时触发
        @Override
        public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
            currentElement = qName;
            if ("book".equals(qName)) {
                // 打印书籍 ID
                System.out.println("书籍 ID: " + attributes.getValue("id"));
                bookInfo.setLength(0); // 清空 bookInfo
            }
        }

        // 当遇到文本内容时触发
        @Override
        public void characters(char[] ch, int start, int length) throws SAXException {
            if (!currentElement.isEmpty()) {
                // 将文本内容追加到 bookInfo 中
                bookInfo.append(new String(ch, start, length));
            }
        }

        // 当遇到结束标签时触发
        @Override
        public void endElement(String uri, String localName, String qName) throws SAXException {
            if ("title".equals(qName)) {
                // 打印书名
                System.out.println("书名: " + bookInfo.toString().trim());
            } else if ("author".equals(qName)) {
                // 打印作者
                System.out.println("作者: " + bookInfo.toString().trim());
            } else if ("year".equals(qName)) {
                // 打印出版年份,并打印分隔线
                System.out.println("出版年份: " + bookInfo.toString().trim());
                System.out.println("----------------------------");
            }
            currentElement = ""; // 重置当前元素
        }
    }
}

运行该代码,输出结果与 DOM 解析示例相同。通过对比可以看出,SAX 解析方式在处理大型 XML 文件时更具优势,因为它不需要一次性加载整个文档到内存,而是逐个处理元素。

生成 XML —— 创建你的数据文档

除了解析 XML 文件,我们有时还需要生成 XML 文档来存储数据。下面是一个使用 DOM 创建 XML 文档并将其保存到文件的示例:

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import java.io.File;

public class XMLCreatorExample {
    public static void main(String[] args) {
        try {
            // 创建 DocumentBuilderFactory 和 DocumentBuilder 对象
            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
            DocumentBuilder builder = factory.newDocumentBuilder();
            // 创建空白文档
            Document document = builder.newDocument();

            // 创建根元素 <library>
            Element library = document.createElement("library");
            document.appendChild(library);

            // 创建第一个 <book> 元素
            Element book1 = document.createElement("book");
            book1.setAttribute("id", "001");
            library.appendChild(book1);

            Element title1 = document.createElement("title");
            title1.appendChild(document.createTextNode("Java 编程思想"));
            book1.appendChild(title1);

            Element author1 = document.createElement("author");
            author1.appendChild(document.createTextNode("Bruce Eckel"));
            book1.appendChild(author1);

            Element year1 = document.createElement("year");
            year1.appendChild(document.createTextNode("2021"));
            book1.appendChild(year1);

            // 创建第二个 <book> 元素
            Element book2 = document.createElement("book");
            book2.setAttribute("id", "002");
            library.appendChild(book2);

            Element title2 = document.createElement("title");
            title2.appendChild(document.createTextNode("数据结构与算法分析"));
            book2.appendChild(title2);

            Element author2 = document.createElement("author");
            author2.appendChild(document.createTextNode("Mark Allen Weiss"));
            book2.appendChild(author2);

            Element year2 = document.createElement("year");
            year2.appendChild(document.createTextNode("2022"));
            book2.appendChild(year2);

            // 使用 Transformer 对象将文档写入文件
            TransformerFactory transformerFactory = TransformerFactory.newInstance();
            Transformer transformer = transformerFactory.newTransformer();
            // 设置输出格式
            transformer.setOutputProperty(OutputKeys.INDENT, "yes");
            DOMSource source = new DOMSource(document);
            StreamResult result = new StreamResult(new File("library.xml"));
            transformer.transform(source, result);

            System.out.println("XML 文档已成功创建!");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

运行该代码后,会在项目目录下生成一个 library.xml 文件,其内容与之前示例中的 XML 内容一致。通过这种方式,我们可以方便地将 Java 程序中的数据以 XML 格式存储起来,方便后续的读取和使用。

三、大显身手

Java 中的 JSON 处理秘籍

Gson 库 —— 简单易用的 JSON 处理利器

Gson 是由 Google 开发的一款功能强大且易于使用的 JSON 处理库。它能够轻松地将 Java 对象转换为 JSON 字符串,也能将 JSON 字符串解析为 Java 对象。下面是一个使用 Gson 库处理 JSON 数据的示例:

import com.google.gson.Gson;
import java.util.ArrayList;
import java.util.List;

class Book {
    private String id;
    private String title;
    private String author;
    private int year;

    public Book(String id, String title, String author, int year) {
        this.id = id;
        this.title = title;
        this.author = author;
        this.year = year;
    }

    // Getter 和 Setter 方法
    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getAuthor() {
        return author;
    }

    public void setAuthor(String author) {
        this.author = author;
    }

    public int getYear() {
        return year;
    }

    public void setYear(int year) {
        this.year = year;
    }
}

public class GsonExample {
    public static void main(String[] args) {
        // 创建书籍列表
        List<Book> books = new ArrayList<>();
        books.add(new Book("001", "Java 编程思想", "Bruce Eckel", 2021));
        books.add(new Book("002", "数据结构与算法分析", "Mark Allen Weiss", 2022));

        // 创建 Gson 对象
        Gson gson = new Gson();

        // 将 Java 对象转换为 JSON 字符串
        String json = gson.toJson(books);
        System.out.println("JSON 字符串: " + json);

        // 将 JSON 字符串解析为 Java 对象
        List<Book> parsedBooks = gson.fromJson(json, new com.google.gson.reflect.TypeToken<List<Book>>() {}.getType());

        // 遍历解析后的书籍列表并打印信息
        System.out.println("解析后的书籍列表:");
        for (Book book : parsedBooks) {
            System.out.println("书籍 ID: " + book.getId());
            System.out.println("书名: " + book.getTitle());
            System.out.println("作者: " + book.getAuthor());
            System.out.println("出版年份: " + book.getYear());
            System.out.println("----------------------------");
        }
    }
}

运行该代码,你将看到如下输出:

JSON 字符串: [{"id":"001","title":"Java 编程思想","author":"Bruce Eckel","year":2021},{"id":"002","title":"数据结构与算法分析","author":"Mark Allen Weiss","year":2022}]
解析后的书籍列表:
书籍 ID: 001
书名: Java 编程思想
作者: Bruce Eckel
出版年份: 2021
----------------------------
书籍 ID: 002
书名: 数据结构与算法分析
作者: Mark Allen Weiss
出版年份: 2022
----------------------------

Jackson 库 —— 功能强大的 JSON 处理专家

Jackson 是另一个广受欢迎的 JSON 处理库,它提供了丰富的功能和灵活的配置选项。与 Gson 相比,Jackson 在处理复杂 JSON 数据结构和大规模数据时表现出色。下面是一个使用 Jackson 库处理 JSON 数据的示例:

import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

class Book {
    private String id;
    private String title;
    private String author;
    private int year;

    public Book(String id, String title, String author, int year) {
        this.id = id;
        this.title = title;
        this.author = author;
        this.year = year;
    }

    // Getter 和 Setter 方法
    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getAuthor() {
        return author;
    }

    public void setAuthor(String author) {
        this.author = author;
    }

    public int getYear() {
        return year;
    }

    public void setYear(int year) {
        this.year = year;
    }
}

public class JacksonExample {
    public static void main(String[] args) {
        // 创建书籍列表
        List<Book> books = new ArrayList<>();
        books.add(new Book("001", "Java 编程思想", "Bruce Eckel", 2021));
        books.add(new Book("002", "数据结构与算法分析", "Mark Allen Weiss", 2022));

        // 创建 ObjectMapper 对象
        ObjectMapper mapper = new ObjectMapper();

        try {
            // 将 Java 对象转换为 JSON 字符串
            String json = mapper.writeValueAsString(books);
            System.out.println("JSON 字符串: " + json);

            // 将 JSON 字符串解析为 Java 对象
            List<Book> parsedBooks = mapper.readValue(json, mapper.getTypeFactory().constructCollectionType(List.class, Book.class));

            // 遍历解析后的书籍列表并打印信息
            System.out.println("解析后的书籍列表:");
            for (Book book : parsedBooks) {
                System.out.println("书籍 ID: " + book.getId());
                System.out.println("书名: " + book.getTitle());
                System.out.println("作者: " + book.getAuthor());
                System.out.println("出版年份: " + book.getYear());
                System.out.println("----------------------------");
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

运行该代码,输出结果与使用 Gson 库的示例相同。Jackson 库在处理 JSON 数据时提供了更多的灵活性和强大功能,特别是在处理复杂的 JSON 数据结构和与 Web 框架集成时表现突出。

四、进阶之路

XML 与 JSON 的相互转换

在实际开发中,我们常常需要在 XML 和 JSON 之间进行数据转换,以满足不同系统和接口的要求。下面将介绍如何在 Java 中实现 XML 与 JSON 的相互转换。

XML 转换为 JSON —— 跨越数据格式的桥梁

我们可以使用 org.json 库中的 XMLJSON 类来实现 XML 到 JSON 的转换。下面是一个将上述 library.xml 文件转换为 JSON 字符串的示例:

import org.json.JSONObject;
import org.json.XML;

public class XMLToJsonExample {
    public static void main(String[] args) {
        // 定义 XML 字符串
        String xml = "<library><book id=\"001\"><title>Java 编程思想</title><author>Bruce Eckel</author><year>2021</year></book><book id=\"002\"><title>数据结构与算法分析</title><author>Mark Allen Weiss</author><year>2022</year></book></library>";

        try {
            // 将 XML 转换为 JSONObject
            JSONObject jsonObject = XML.toJSONObject(xml);
            // 将 JSONObject 转换为格式化的 JSON 字符串
            String json = jsonObject.toString(4); // 4 是缩进字符数
            System.out.println("JSON 字符串: " + json);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

运行该代码,你将看到如下输出:

JSON 字符串: {
    "library": {
        "book": [
            {
                "id": "001",
                "title": "Java 编程思想",
                "author": "Bruce Eckel",
                "year": 2021
            },
            {
                "id": "002",
                "title": "数据结构与算法分析",
                "author": "Mark Allen Weiss",
                "year": 2022
            }
        ]
    }
}

JSON 转换为 XML —— 反向转换的魔法

同样,我们可以使用 org.json 库中的 XML 类来实现 JSON 到 XML 的转换。下面是一个将上述 JSON 字符串转换回 XML 字符串的示例:

import org.json.JSONObject;
import org.json.XML;

public class JsonToXMLExample {
    public static void main(String[] args) {
        // 定义 JSON 字符串
        String json = "{\"library\":{\"book\":[{\"id\":\"001\",\"title\":\"Java 编程思想\",\"author\":\"Bruce Eckel\",\"year\":2021},{\"id\":\"002\",\"title\":\"数据结构与算法分析\",\"author\":\"Mark Allen Weiss\",\"year\":2022}]}";

        try {
            // 将 JSON 字符串转换为 JSONObject
            JSONObject jsonObject = new JSONObject(json);
            // 将 JSONObject 转换为 XML 字符串
            String xml = XML.toString(jsonObject);
            System.out.println("XML 字符串: " + xml);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

运行该代码,你将看到如下输出:

XML 字符串: <?xml version="1.0" encoding="UTF-8"?><library><book id="001"><title>Java 编程思想</title><author>Bruce Eckel</author><year>2021</year></book><book id="002"><title>数据结构与算法分析</title><author>Mark Allen Weiss</author><year>2022</year></book></library>

五、化繁为简

选择合适的数据处理方式

在 Java 开发中,选择合适的数据处理方式至关重要。XML 和 JSON 各有特点和适用场景:

  • XML :适用于需要严格结构化、具有复杂层次关系和属性的数据。例如,配置文件、文档内容、企业级数据交换等。XML 的优势在于其强大的结构描述能力和广泛的行业支持,但其缺点是体积较大,解析和生成相对复杂。

  • JSON :适用于网络数据传输、轻量级数据存储、前端与后端交互等场景。JSON 的优势在于简洁、易于阅读和编写、体积小、解析和生成效率高。但其在描述复杂结构和属性方面不如 XML 强大。

在实际项目中,我们应根据具体需求和场景来选择合适的数据格式和处理方式。例如,在构建 Web API 时,通常使用 JSON 作为数据传输格式,因为它与 JavaScript 的天然亲和性使得前端处理更加便捷。而在处理复杂的配置文件或企业级数据交换时,XML 可能是更合适的选择。

总结

掌握 Java 中 XML 和 JSON 的处理技巧,是每个 Java 开发者必备的技能之一。通过本文的深入讲解和实例演示,我们从基础概念入手,逐步深入到实际的代码操作,涵盖了 XML 和 JSON 的解析、生成以及相互转换等方面的内容。希望这些知识和示例能够帮助你在实际开发中更加得心应手地处理数据。

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐