杰瑞科技汇

java string转换成xml

  1. DOM (Document Object Model) 方式:将整个 XML 文档读入内存,形成一个树形结构,这种方式简单直观,适合小型 XML 文件,但如果 XML 文件很大,会消耗大量内存。
  2. SAX (Simple API for XML) / StAX (Streaming API for XML) 方式:事件驱动的解析方式,逐行读取 XML 文件,不会一次性加载整个文档到内存,这种方式性能好,内存占用低,适合处理大型 XML 文件。

下面我将详细介绍这两种方式,并提供完整的代码示例。

java string转换成xml-图1
(图片来源网络,侵删)

准备工作:确保你的字符串是有效的 XML

你需要确保你想要转换的字符串是一个格式良好的 XML,它必须有且仅有一个根元素,所有标签都必须正确闭合。

一个有效的 XML 字符串示例:

<?xml version="1.0" encoding="UTF-8"?>
<library>
    <book id="001">
        <title>Java Programming</title>
        <author>John Doe</author>
        <price currency="USD">39.99</price>
    </book>
    <book id="002">
        <title>Learning XML</title>
        <author>Jane Smith</author>
        <price currency="EUR">29.50</price>
    </book>
</library>

使用 DOM (Document Object Model)

DOM 是最常见和最简单的方法,Java 标准库 javax.xml.parsers 提供了 DOM 解析器。

核心类

  • DocumentBuilderFactory: 创建 DocumentBuilder 的工厂类。
  • DocumentBuilder: 负责将 XML 源(如文件、输入流、字符串)解析成 Document 对象。
  • Document: 代表整个 XML 文档的内存树形结构。
  • Node: DocumentElement 等所有节点的基类。
  • Element: 代表 XML 中的一个元素(标签)。

完整代码示例

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.StringReader;
public class StringToXmlDom {
    public static void main(String[] args) {
        // 1. 定义你的 XML 字符串
        String xmlString = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
                + "<library>"
                + "    <book id=\"001\">"
                + "        <title>Java Programming</title>"
                + "        <author>John Doe</author>"
                + "        <price currency=\"USD\">39.99</price>"
                + "    </book>"
                + "    <book id=\"002\">"
                + "        <title>Learning XML</title>"
                + "        <author>Jane Smith</author>"
                + "        <price currency=\"EUR\">29.50</price>"
                + "    </book>"
                + "</library>";
        try {
            // 2. 创建 DocumentBuilderFactory 和 DocumentBuilder
            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
            DocumentBuilder builder = factory.newDocumentBuilder();
            // 3. 将字符串转换为输入流并解析成 Document 对象
            // 注意:StringReader 是 Reader 的实现,DocumentBuilder 也能处理
            Document document = builder.parse(new InputSource(new StringReader(xmlString)));
            // 4. (可选) 规范化文档,确保文本节点等被正确处理
            document.getDocumentElement().normalize();
            // 5. 开始遍历和操作 XML 树
            System.out.println("根元素: " + document.getDocumentElement().getNodeName());
            // 获取所有 'book' 节点
            NodeList bookList = document.getElementsByTagName("book");
            // 遍历 bookList
            for (int i = 0; i < bookList.getLength(); i++) {
                Node node = bookList.item(i);
                if (node.getNodeType() == Node.ELEMENT_NODE) {
                    Element element = (Element) node;
                    System.out.println("\n当前 Book ID: " + element.getAttribute("id"));
                    // 获取 'title' 元素
                    NodeList titleList = element.getElementsByTagName("title");
                    Element titleElement = (Element) titleList.item(0);
                    System.out.println("标题: " + titleElement.getTextContent());
                    // 获取 'author' 元素
                    NodeList authorList = element.getElementsByTagName("author");
                    Element authorElement = (Element) authorList.item(0);
                    System.out.println("作者: " + authorElement.getTextContent());
                    // 获取 'price' 元素及其属性
                    NodeList priceList = element.getElementsByTagName("price");
                    Element priceElement = (Element) priceList.item(0);
                    System.out.println("价格: " + priceElement.getTextContent() + " " + priceElement.getAttribute("currency"));
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            System.err.println("XML 解析错误: " + e.getMessage());
        }
    }
}

输出结果:

java string转换成xml-图2
(图片来源网络,侵删)
根元素: library
当前 Book ID: 001 Java Programming
作者: John Doe
价格: 39.99 USD
当前 Book ID: 002 Learning XML
作者: Jane Smith
价格: 29.50 EUR

使用 StAX (Streaming API for XML)

StAX 是一种更现代、更高效的流式 API,它允许你以“拉取”(pull)的方式读取 XML 事件,对于大型文件,StAX 的性能和内存效率远超 DOM。

核心类

  • XMLInputFactory: 创建 XMLStreamReader 的工厂类。
  • XMLStreamReader: 逐个读取 XML 事件(如开始元素、结束元素、字符数据等)的读取器。

完整代码示例

import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamConstants;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import java.io.StringReader;
public class StringToXmlStax {
    public static void main(String[] args) {
        String xmlString = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
                + "<library>"
                + "    <book id=\"001\">"
                + "        <title>Java Programming</title>"
                + "        <author>John Doe</author>"
                + "        <price currency=\"USD\">39.99</price>"
                + "    </book>"
                + "    <book id=\"002\">"
                + "        <title>Learning XML</title>"
                + "        <author>Jane Smith</author>"
                + "        <price currency=\"EUR\">29.50</price>"
                + "    </book>"
                + "</library>";
        XMLInputFactory factory = XMLInputFactory.newInstance();
        try {
            // 创建 XMLStreamReader
            XMLStreamReader reader = factory.createXMLStreamReader(new StringReader(xmlString));
            String currentElement = null;
            String currentId = null;
            // 遍历所有 XML 事件
            while (reader.hasNext()) {
                int event = reader.next();
                switch (event) {
                    case XMLStreamConstants.START_ELEMENT:
                        // 当遇到一个开始标签时
                        if ("book".equals(reader.getLocalName())) {
                            currentId = reader.getAttributeValue(null, "id");
                            System.out.println("\n当前 Book ID: " + currentId);
                        } else if ("title".equals(reader.getLocalName()) || "author".equals(reader.getLocalName()) || "price".equals(reader.getLocalName())) {
                            currentElement = reader.getLocalName();
                        }
                        break;
                    case XMLStreamConstants.CHARACTERS:
                        // 当遇到字符数据时
                        if (currentElement != null) {
                            String text = reader.getText().trim();
                            if (!text.isEmpty()) {
                                switch (currentElement) {
                                    case "title":
                                        System.out.println("标题: " + text);
                                        break;
                                    case "author":
                                        System.out.println("作者: " + text);
                                        break;
                                    case "price":
                                        String currency = reader.getAttributeValue(null, "currency");
                                        System.out.println("价格: " + text + " " + currency);
                                        break;
                                }
                            }
                        }
                        break;
                    case XMLStreamConstants.END_ELEMENT:
                        // 当遇到一个结束标签时
                        if ("book".equals(reader.getLocalName())) {
                            currentId = null;
                        }
                        currentElement = null; // 重置当前元素
                        break;
                }
            }
            reader.close();
        } catch (XMLStreamException e) {
            e.printStackTrace();
            System.err.println("StAX 解析错误: " + e.getMessage());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

输出结果:

当前 Book ID: 001 Java Programming
作者: John Doe
价格: 39.99 USD
当前 Book ID: 002 Learning XML
作者: Jane Smith
价格: 29.50 EUR

总结与对比

特性 DOM (Document Object Model) StAX (Streaming API for XML)
处理方式 将整个 XML 文档加载到内存中,形成树状结构。 事件驱动,逐行读取,不一次性加载整个文档。
内存消耗 高,与 XML 文件大小成正比。 低,内存占用恒定,适合大文件。
性能 较慢,尤其是在构建整个树时。 较快,特别是对于只读操作。
易用性 非常简单直观,易于理解和使用,适合小型文件和快速开发。 相对复杂,需要手动处理事件和状态管理。
适用场景 - XML 文件较小。
- 需要频繁地在文档中任意位置进行读写操作。
- 开发时间短,希望代码简单。
- XML 文件非常大。
- 只需要遍历一次 XML 文件。
- 对内存和性能有严格要求。

如何选择?

  • 对于初学者或小型项目:直接使用 DOM,它最简单,代码量少,不容易出错。
  • 对于处理大型 XML 文件或企业级应用:强烈推荐使用 StAXSAX,它能有效避免 OutOfMemoryError,并提供更好的性能。

还有像 JDOMDOM4J 这样的第三方库,它们提供了比标准 DOM 更友好、更强大的 API,是许多 Java 项目的首选,但如果不想引入额外依赖,标准的 javax.xml 包已经足够强大。

分享:
扫描分享到社交APP
上一篇
下一篇