1. 概述

在Java中处理XML时,我们经常需要将org.w3c.dom.Document实例转换为String这种转换通常用于序列化、日志记录,以及处理HTTP请求/响应等场景。

本教程将介绍几种将Document对象转换为字符串的方法。想了解更多Java XML处理技巧?可以参考我们的XML系列教程

2. 创建简单Document对象

本教程将使用以下描述水果的简单XML文档作为示例:

<fruit>
    <name>Apple</name>
    <color>Red</color>
    <weight unit="grams">150</weight>
    <sweetness>7</sweetness>
</fruit>

现在我们创建对应的XML Document对象:

private static final String FRUIT_XML = "<fruit><name>Apple</name><color>Red</color><weight unit=\"grams\">150</weight><sweetness>7</sweetness></fruit>"; 

public static Document getDocument() throws SAXException, IOException, ParserConfigurationException {
    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
    Document document = factory.newDocumentBuilder()
      .parse(new InputSource(new StringReader(FRUIT_XML)));
    return document;
}

这段代码的核心逻辑:

  1. 创建DocumentBuilderFactory实例
  2. 通过工厂创建DocumentBuilder
  3. 使用StringReader解析XML字符串
  4. 返回构建的Document对象

⚠️ 注意:实际开发中记得处理异常,这里为简化示例省略了try-catch

3. 使用XML转换API实现转换

javax.xml.transform包提供了通用的源到结果转换API。我们的转换场景中:

  • 源:XML文档
  • 结果:输出字符串
public static String toString(Document document) throws TransformerException {
    TransformerFactory transformerFactory = TransformerFactory.newInstance();
    Transformer transformer = transformerFactory.newTransformer();
    StringWriter stringWriter = new StringWriter();
    transformer.transform(new DOMSource(document), new StreamResult(stringWriter));
    return stringWriter.toString();
}

关键步骤解析:

  1. 创建TransformerFactory实例
  2. 通过工厂获取默认的Transformer
  3. 使用StringWriter作为输出目标
  4. 执行转换:DOMSource包装Document,StreamResult包装Writer
  5. 返回Writer中的字符串内容

✅ 这种方式是Java标准库提供的原生解决方案,无需额外依赖

4. 单元测试验证

现在测试我们的转换方法是否正常工作:

@Test
public void givenXMLDocument_thenConvertToStringSuccessfully() throws Exception {
    Document document = XmlDocumentToString.getDocument();

    String expectedDeclartion = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>";
    assertEquals(expectedDeclartion + XmlDocumentToString.FRUIT_XML, XmlDocumentToString.toString(document));
}

注意转换结果会自动添加标准XML声明。测试中我们验证了:

  • 转换后的字符串包含正确的XML声明
  • 声明后紧跟着原始XML内容

❌ 常见踩坑点:测试时容易忽略XML声明,导致断言失败

5. 自定义输出格式

默认转换结果没有格式化,可读性较差:

<?xml version="1.0" encoding="UTF-8" standalone="no"?><fruit><name>Apple</name><color>Red</color><weight unit="grams">150</weight><sweetness>7</sweetness></fruit>

对于复杂XML文档,这种单行输出几乎无法阅读。好在Transformer提供了丰富的输出属性配置:

public static String toStringWithOptions(Document document) throws TransformerException {
    Transformer transformer = getTransformer();
    transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
    transformer.setOutputProperty(OutputKeys.INDENT, "yes");
    transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4");

    StringWriter stringWriter = new StringWriter();
    transformer.transform(new DOMSource(document), new StreamResult(stringWriter));
    return stringWriter.toString();
}

private static Transformer getTransformer() throws TransformerConfigurationException {
    TransformerFactory transformerFactory = TransformerFactory.newInstance();
    return transformerFactory.newTransformer();
}

关键配置说明:

  1. OMIT_XML_DECLARATION:移除XML声明(设为"yes")
  2. INDENT:启用缩进(设为"yes")
  3. indent-amount:设置缩进量(这里设为4个空格)

优化后的输出效果:

<fruit>
    <name>Apple</name>
    <color>Red</color>
    <weight unit="grams">150</weight>
    <sweetness>7</sweetness>
</fruit>

✅ 这种格式化输出特别适合:

  • 日志记录
  • 调试输出
  • 生成人类可读的XML文档

6. 总结

本文介绍了在Java中处理XML文档转换的核心技巧:

  1. 从字符串创建Document对象
  2. 使用javax.xml.transform包实现Document到String的转换
  3. 通过输出属性自定义XML格式

这些方法在需要序列化XML或进行日志记录时特别实用。完整示例代码可在GitHub仓库获取。


原始标题:How to Convert org.w3c.dom.Document to String in Java | Baeldung