将 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 parser
System.out.println("\n** Parsing error"
+ ", line " + spe.getLineNumber()
+ ", uri " + spe.getSystemId());
System.out.println(" " + spe.getMessage() );
// Use the contained exception, if any
Exception 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 built
pce.printStackTrace();
}
catch (IOException ioe) {
// I/O error
ioe.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 output
TransformerFactory 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
TransformationApp01
sample.键入以下命令:
% javac TransformationApp01.java
Run the
TransformationApp01
sample 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
TranformationApp02
sample.键入以下命令:
% javac xslt/TranformationApp02.java
Run the
TranformationApp02
sample on an XML file.在下面的情况中,
TranformationApp02
在解压缩样例包后,在xslt / data
目录中找到的文件foo.xml
上运行。% java TranformationApp02 data/foo.xml
您将看到以下输出:
<?xml version="1.0" encoding="UTF-8"
standalone="no"?><doc><name
first="David" last="Marston"/>
这次,只有第一个
< name>打印出
元素。此时,您已经了解了如何使用转换器来编写 DOM 以及如何使用 DOM 的子树作为转换中的源对象。在下一节中,您将了解如何使用转换器从您能够解析的任何数据结构中创建 XML。