可扩展样式表语言转换(XSLT)标准定义类,用于使用XPath寻址XML数据和进行转换数据以其他形式。
JAXP包括XSLT的解释实现。
可扩展样式表语言(XSL)有三个主要子组件:
| 组件 | 描述 |
|---|---|
| XSL-FO | 格式化对象标准。 我们可以定义字体大小,页面布局和对象呈现的其他方面。 |
| XSLT | 它定义了从XML到其他格式的转换。例如,使用XSLT从XML文档生成HTML。 |
| XPath | XPath是一种规范语言,我们可以用它来创建一个元素的路径。 |
以下是对JAXP Transformation API的包的描述:
| 包 | 描述 |
|---|---|
| javax.xml.transform | 这个包定义了返回Transformer对象的工厂类。 我们可以使用输入和输出对象配置Transformer,并调用其transform()方法来执行转换。 |
| javax.xml.transform.dom | 定义DOMSource和DOMResult类,用于将DOM用作转换中的输入或输出。 |
| javax.xml.transform.sax | 定义SAXSource和SAXResult类,用于在转换中使用SAX作为输入或输出。 |
| javax.xml.transform.stream | 定义StreamSource和StreamResult类,以将I/O流用作转换的输入或输出。 |
XPath表达式指定用于选择一组XML节点的模式。
XSLT模板可以使用这些模式来选择节点并应用转换。
使用XPath表达式,我们可以引用元素的文本和属性。XPath规范定义了七种类型的节点:
根
元素
文本
属性
注释
处理指令
命名空间
XML文档是树结构的节点集合。
XPath使用路径符号在XML中寻址节点。
正斜杠/是路径分隔符。
文档根目录的绝对路径以/开头。
相对路径可以从任何其他开始。
双重周期..表示父节点。
单个期间.表示当前节点。
在XPath /h1/h2 中选择位于h1元素下的所有h2元素。
要选择一个特定的h2元素,我们使用方括号 [] 来索引。
例如, /h1[4]/h2 [5] 将选择第五个 h2 在第四个 h1 元素下。
要引用属性,请在属性名称前加上@符号。例如, @type 是指 type 属性。
h1/@type选择 h1 元素的 type 属性。
XPath表达式可以使用通配符,运算符及其自身的函数。
表达式 @type="unordered"指定一个属性名为 type ,其值为无序。
表达式 h1[@ type="unordered"] 选择所有 h1 元素其 type 属性值是无序的。
假设我们将电话数据存储在以下XML文档中。
<PHONEBOOK>
<PERSON>
<NAME>Joe Wang</NAME>
<EMAIL>joe@yourserver.com</EMAIL>
<TELEPHONE>202-999-9999</TELEPHONE>
<WEB>www.lmonkey.com</WEB>
</PERSON>
<PERSON>
<NAME>Karol</name>
<EMAIL>karol@yourserver.com</EMAIL>
<TELEPHONE>306-999-9999</TELEPHONE>
<WEB>www.wlmonkey.com</WEB>
</PERSON>
<PERSON>
<NAME>Green</NAME>
<EMAIL>green@yourserver.com</EMAIL>
<TELEPHONE>202-414-9999</TELEPHONE>
<WEB>www.lmonkey.com</WEB>
</PERSON>
</PHONEBOOK>
我们将使用以下XSLT将上述XML转换为HTML文件。
<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:template match="/">
<html>
<head>
<title>Directory</title>
</head>
<body>
<table border="1">
<tr>
<th>Name</th>
<th>Telephone</th>
<th>Email</th>
</tr>
<xsl:for-each select="PHONEBOOK/PERSON">
<xsl:sort/>
<tr>
<td><xsl:value-of select="NAME"/></td>
<td><xsl:value-of select="TELEPHONE"/></td>
<td><xsl:value-of select="EMAIL"/></td>
</tr>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
从上面的代码,我们可以看到数据将被转换为HTML表。
我们使用下面的代码来做转换。
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
public class Main {
public static void main(String args[]) throws Exception {
StreamSource source = new StreamSource(args[0]);
StreamSource stylesource = new StreamSource(args[1]);
TransformerFactory factory = TransformerFactory.newInstance();
Transformer transformer = factory.newTransformer(stylesource);
StreamResult result = new StreamResult(System.out);
transformer.transform(source, result);
}
}
以下代码显示了如何使用Stax解析器转换xml。
import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import javax.xml.XMLConstants;
import javax.xml.stream.XMLEventReader;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLOutputFactory;
import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import javax.xml.validation.Validator;
public class Main {
public static void main(String[] args) throws Exception {
SchemaFactory sf = SchemaFactory
.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
System.out.println("schema factory instance obtained is " + sf);
Schema schema = sf.newSchema(new File(args[0]));
System.out.println("schema obtained is = " + schema);
Validator validator = schema.newValidator();
String fileName = args[1].toString();
String fileName2 = args[2].toString();
javax.xml.transform.Result xmlResult = new javax.xml.transform.stax.StAXResult(
XMLOutputFactory.newInstance().createXMLStreamWriter(
new FileWriter(fileName2)));
javax.xml.transform.Source xmlSource = new javax.xml.transform.stax.StAXSource(
getXMLEventReader(fileName));
validator.validate(new StreamSource(args[1]));
validator.validate(xmlSource, xmlResult);
}
private static XMLEventReader getXMLEventReader(String filename)
throws Exception {
XMLInputFactory xmlif = null;
XMLEventReader xmlr = null;
xmlif = XMLInputFactory.newInstance();
xmlif.setProperty(XMLInputFactory.IS_REPLACING_ENTITY_REFERENCES,
Boolean.TRUE);
xmlif.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES,
Boolean.FALSE);
xmlif.setProperty(XMLInputFactory.IS_NAMESPACE_AWARE, Boolean.TRUE);
xmlif.setProperty(XMLInputFactory.IS_COALESCING, Boolean.TRUE);
FileInputStream fis = new FileInputStream(filename);
xmlr = xmlif.createXMLEventReader(filename, fis);
return xmlr;
}
}
以下代码使用 DOMSource 作为变换输入。
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Document;
import org.xml.sax.InputSource;
public class Main {
public static void main(String[] argv) throws Exception {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse(new InputSource(new InputStreamReader(new FileInputStream(
"inputFile.xml"))));
Transformer xformer = TransformerFactory.newInstance().newTransformer();
xformer.setOutputProperty(OutputKeys.METHOD, "xml");
xformer.setOutputProperty(OutputKeys.INDENT, "yes");
xformer.setOutputProperty("http://xml.apache.org/xslt;indent-amount", "4");
xformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
Source source = new DOMSource(document);
Result result = new StreamResult(new **File**("result.xml"));
xformer.transform(source, result);
}
}
以下代码显示了如何使用XPath更改特定元素。
import java.io.File;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathFactory;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
public class Main {
public static void main(String[] args) throws Exception {
Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(
new InputSource("data.xml"));
XPath xpath = XPathFactory.newInstance().newXPath();
NodeList nodes = (NodeList) xpath.evaluate("//employee/name[text()="old"]", doc,
XPathConstants.NODESET);
for (int idx = 0; idx < nodes.getLength(); idx++) {
nodes.item(idx).setTextContent("new value");
}
Transformer xformer = TransformerFactory.newInstance().newTransformer();
xformer.transform(new DOMSource(doc), new StreamResult(new File("data_new.xml")));
}
}
© 著作权归作者所有