将 DOM 写为 XML 文件
原文: https://docs.oracle.com/javase/tutorial/jaxp/xslt/writingDom.html
构建 DOM(通过解析 XML 文件或以编程方式构建它)之后,您经常要将其另存为 XML。本节介绍如何使用 Xalan 转换包执行此操作。
使用该包,您将创建一个变换器对象,以将DOMSource连接到StreamResult 。然后,您将调用转换器的transform()方法将 DOM 写为 XML 数据。
阅读 XML
第一步是通过解析 XML 文件在内存中创建 DOM。到现在为止,您应该对这个过程感到满意。
Note:
本节中讨论的代码位于文件TransformationApp01.java中。 Download the XSLT examlles 并将它们解压缩到 install-dir / jaxp-1_4_2- 发布日期 /样例 ] 目录。
以下代码提供了一个基本模板。它基本上与文档对象模型课程开头时使用的代码相同。
import javax.xml.parsers.DocumentBuilder;import javax.xml.parsers.DocumentBuilderFactory;import javax.xml.parsers.FactoryConfigurationError;import javax.xml.parsers.ParserConfigurationException;import org.xml.sax.SAXException;import org.xml.sax.SAXParseException;import org.w3c.dom.Document;import org.w3c.dom.DOMException;import java.io.*;public class TransformationApp01 {static Document document;public static void main(String argv[]) {if (argv.length != 1) {System.err.println("Usage: java TransformationApp01 filename");System.exit (1);}DocumentBuilderFactory factory =DocumentBuilderFactory.newInstance();try {File f = new File(argv[0]);DocumentBuilder builder =factory.newDocumentBuilder();document = builder.parse(f);}catch (SAXParseException spe) {// Error generated by the parserSystem.out.println("\n** Parsing error"+ ", line " + spe.getLineNumber()+ ", uri " + spe.getSystemId());System.out.println(" " + spe.getMessage() );// Use the contained exception, if anyException x = spe;if (spe.getException() != null)x = spe.getException();x.printStackTrace();}catch (SAXException sxe) {// Error generated by this application// (or a parser-initialization error)Exception x = sxe;if (sxe.getException() != null)x = sxe.getException();x.printStackTrace();}catch (ParserConfigurationException pce) {// Parser with specified options// cannot be builtpce.printStackTrace();}catch (IOException ioe) {// I/O errorioe.printStackTrace();}}}
创建一个变压器
下一步是创建一个可用于将 XML 传输到System.out的转换器。首先,需要以下 import 语句。
import javax.xml.transform.Transformer;import javax.xml.transform.TransformerFactory;import javax.xml.transform.TransformerException;import javax.xml.transform.TransformerConfigurationException;import javax.xml.transform.dom.DOMSource;import javax.xml.transform.stream.StreamResult;import java.io.*;
在这里,您添加了一系列现在应该形成标准模式的类:实体( Transformer ),创建它的工厂( TransformerFactory ),以及可以的异常由每个人产生。因为转换总是有源和结果,所以然后导入使用 DOM 作为源( DOMSource )所需的类和结果的输出流( StreamResult )。
接下来,添加代码以执行转换:
try {File f = new File(argv[0]);DocumentBuilder builder = factory.newDocumentBuilder();document = builder.parse(f);// Use a Transformer for outputTransformerFactory tFactory =TransformerFactory.newInstance();Transformer transformer =tFactory.newTransformer();DOMSource source = new DOMSource(document);StreamResult result = new StreamResult(System.out);transformer.transform(source, result);}
在这里,您创建一个转换器对象,使用 DOM 构造一个源对象,并使用System.out构造一个结果对象。然后告诉变换器对源对象进行操作并输出到结果对象。
在这种情况下,“变压器”实际上并没有改变任何东西。在 XSLT 术语中,您使用的是身份转换,这意味着“转换”会生成源的副本,不会更改。
Note:
您可以为变换器对象指定各种输出属性,如 http://www.w3.org/TR/xslt#output 中的 W3C 规范中所定义。例如,要获取缩进输出,可以调用以下方法:
% transformer.setOutputProperty(OutputKeys.INDENT, "yes");
最后,以下突出显示的代码捕获了可生成的新错误:
}catch (TransformerConfigurationException tce) {System.out.println("* Transformer Factory error");System.out.println(" " + tce.getMessage());Throwable x = tce;if (tce.getException() != null)x = tce.getException();x.printStackTrace();}catch (TransformerException te) {System.out.println("* Transformation error");System.out.println(" " + te.getMessage());Throwable x = te;if (te.getException() != null)x = te.getException();x.printStackTrace();}catch (SAXParseException spe) {// ...}
备注
TransformerExceptions由变换器对象抛出。TransformerConfigurationExceptions由工厂抛出。要保留 XML 文档的
DOCTYPE设置,还需要添加以下代码:import javax.xml.transform.OutputKeys;...if (document.getDoctype() != null) {String systemValue = (new File (document.getDoctype().getSystemId())).getName();transformer.setOutputProperty(OutputKeys.DOCTYPE_SYSTEM, systemValue);}
要了解有关配置工厂和处理验证错误的更多信息,请参阅将 XML 数据读入 DOM 。
运行TransformationApp01示例
导航至
样例目录。%cd install-dir / jaxp-1_4_2- 释放日期 /样例。
Download the XSLT examples by clicking this link并将它们解压缩到 install-dir/ jaxp-1_4_2-释放日期/样例目录。导航到
xslt目录。% cd xslt
Compile the
TransformationApp01sample.键入以下命令:
% javac TransformationApp01.java
Run the
TransformationApp01sample on an XML file.在下面的例子中,
TransformationApp01在解压缩样例包后在xslt / data目录中找到的文件foo.xml上运行。% java TransformationApp01 data/foo.xml
您将看到以下输出:
<?xml version="1.0"encoding="UTF-8"standalone="no"?><doc><name first="David" last="Marston"/><name first="David" last="Bertoni"/><name first="Donald" last="Leslie"/><name first="Emily" last="Farmer"/><name first="Joseph" last="Kesselman"/><name first="Myriam" last="Midy"/><name first="Paul" last="Dick"/><name first="Stephen" last="Auriemma"/><name first="Scott" last="Boag"/><name first="Shane" last="Curcuru"/>
正如创建变换器中所提到的,这个变换器实际上并没有改变任何东西,而是刚刚执行了身份变换,以生成源的副本。将在从任意数据结构生成 XML 中执行真正的转换。
写出 DOM 的子树
也可以在 DOM 的子树上操作。在本节中,您将尝试该选项。
Note:
本节中讨论的代码位于 TranformationApp02.java 中。如果你还没有这样做, download the XSLT examples 并将它们解压缩到 install-dir / jaxp-1_4_2- 发布日期 ] / samples目录。
该过程的唯一区别是,现在您将使用 DOM 中的节点而不是整个 DOM 创建DOMSource 。第一步是导入获取所需节点所需的类,如以下突出显示的代码所示:
import org.w3c.dom.Document;import org.w3c.dom.DOMException;import org.w3c.dom.Node;import org.w3c.dom.NodeList;
下一步是为实验找到一个好的节点。以下突出显示的代码选择第一个< name>元素。
try {File f = new File(argv[0]);DocumentBuilder builder = factory.newDocumentBuilder();document = builder.parse(f);NodeList list = document.getElementsByTagName("name");Node node = list.item(0);}
在创建变换器中,源对象是通过以下代码行从整个文档构造的
DOMSource source = new DOMSource(document);
但是,下面突出显示的代码行构造了一个源对象,该对象由以特定节点为根的子树组成。
DOMSource source = new DOMSource(node);StreamResult result = new StreamResult(System.out);transformer.transform(source, result);
运行TranformationApp02样例
导航至
样例目录。%cd install-dir / jaxp-1_4_2- 释放日期 /样例。
Download the XSLT examples by clicking this link并将它们解压缩到 install-dir/ jaxp-1_4_2-释放日期/样例目录。导航到
xslt目录。cd xslt
Compile the
TranformationApp02sample.键入以下命令:
% javac xslt/TranformationApp02.java
Run the
TranformationApp02sample on an XML file.在下面的情况中,
TranformationApp02在解压缩样例包后,在xslt / data目录中找到的文件foo.xml上运行。% java TranformationApp02 data/foo.xml
您将看到以下输出:
<?xml version="1.0" encoding="UTF-8"standalone="no"?><doc><namefirst="David" last="Marston"/>
这次,只有第一个
< name>打印出元素。此时,您已经了解了如何使用转换器来编写 DOM 以及如何使用 DOM 的子树作为转换中的源对象。在下一节中,您将了解如何使用转换器从您能够解析的任何数据结构中创建 XML。
