Java XSLT
Java XML教程 - Java XSLT
可扩展样式表语言转换(XSLT)标准定义类,用于使用XPath寻址XML数据和进行转换数据以其他形式。
JAXP包括XSLT的解释实现。
XSL,XSLT和XPath
可扩展样式表语言(XSL)有三个主要子组件:
组件 | 描述 |
---|---|
XSL-FO | 格式化对象标准。 我们可以定义字体大小,页面布局和对象呈现的其他方面。 |
XSLT | 它定义了从XML到其他格式的转换。例如,使用XSLT从XML文档生成HTML。 |
XPath | XPath是一种规范语言,我们可以用它来创建一个元素的路径。 |
JAXP转换包
以下是对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规范定义了七种类型的节点:
- 根
- 元素
- 文本
- 属性
- 注释
- 处理指令
- 命名空间
XPath寻址
XML文档是树结构的节点集合。
XPath使用路径符号在XML中寻址节点。
- 正斜杠/是路径分隔符。
- 文档根目录的绝对路径以/开头。
- 相对路径可以从任何其他开始。
- 双重周期
..
表示父节点。 - 单个期间
.
表示当前节点。
在XPath /h1/h2
中选择位于h1元素下的所有h2元素。
要选择一个特定的h2元素,我们使用方括号 []
来索引。
例如, /h1[4]/h2 [5]
将选择第五个 h2
在第四个 h1
元素下。
要引用属性,请在属性名称前加上@符号。例如, @type
是指 type
属性。
h1/@type
选择 h1
元素的 type
属性。
XPath表达式
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.w3cschool.cn</WEB> </PERSON> <PERSON> <NAME>Karol</name> <EMAIL>karol@yourserver.com</EMAIL> <TELEPHONE>306-999-9999</TELEPHONE> <WEB>www.w3cschool.cn</WEB> </PERSON> <PERSON> <NAME>Green</NAME> <EMAIL>green@yourserver.com</EMAIL> <TELEPHONE>202-414-9999</TELEPHONE> <WEB>www.w3cschool.cn</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); } }
例2
以下代码显示了如何使用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; } }
例3
以下代码使用 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); } }
例4
以下代码显示了如何使用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"))); } }
更多建议: