可擴(kuò)展樣式表語言轉(zhuǎn)換(XSLT)標(biāo)準(zhǔn)定義類,用于使用XPath尋址XML數(shù)據(jù)和進(jìn)行轉(zhuǎn)換數(shù)據(jù)以其他形式。
JAXP包括XSLT的解釋實(shí)現(xiàn)。
可擴(kuò)展樣式表語言(XSL)有三個(gè)主要子組件:
組件 | 描述 |
---|---|
XSL-FO | 格式化對象標(biāo)準(zhǔn)。 我們可以定義字體大小,頁面布局和對象呈現(xiàn)的其他方面。 |
XSLT | 它定義了從XML到其他格式的轉(zhuǎn)換。例如,使用XSLT從XML文檔生成HTML。 |
XPath | XPath是一種規(guī)范語言,我們可以用它來創(chuàng)建一個(gè)元素的路徑。 |
以下是對JAXP Transformation API的包的描述:
包 | 描述 |
---|---|
javax.xml.transform | 這個(gè)包定義了返回Transformer對象的工廠類。 我們可以使用輸入和輸出對象配置Transformer,并調(diào)用其transform()方法來執(zhí)行轉(zhuǎn)換。 |
javax.xml.transform.dom | 定義DOMSource和DOMResult類,用于將DOM用作轉(zhuǎn)換中的輸入或輸出。 |
javax.xml.transform.sax | 定義SAXSource和SAXResult類,用于在轉(zhuǎn)換中使用SAX作為輸入或輸出。 |
javax.xml.transform.stream | 定義StreamSource和StreamResult類,以將I/O流用作轉(zhuǎn)換的輸入或輸出。 |
XPath表達(dá)式指定用于選擇一組XML節(jié)點(diǎn)的模式。
XSLT模板可以使用這些模式來選擇節(jié)點(diǎn)并應(yīng)用轉(zhuǎn)換。
使用XPath表達(dá)式,我們可以引用元素的文本和屬性。XPath規(guī)范定義了七種類型的節(jié)點(diǎn):
XML文檔是樹結(jié)構(gòu)的節(jié)點(diǎn)集合。
XPath使用路徑符號(hào)在XML中尋址節(jié)點(diǎn)。
..
表示父節(jié)點(diǎn)。.
表示當(dāng)前節(jié)點(diǎn)。在XPath /h1/h2
中選擇位于h1元素下的所有h2元素。
要選擇一個(gè)特定的h2元素,我們使用方括號(hào) []
來索引。
例如, /h1[4]/h2 [5]
將選擇第五個(gè) h2
在第四個(gè) h1
元素下。
要引用屬性,請?jiān)趯傩悦Q前加上@符號(hào)。例如, @type
是指 type
屬性。
h1/@type
選擇 h1
元素的 type
屬性。
XPath表達(dá)式可以使用通配符,運(yùn)算符及其自身的函數(shù)。
表達(dá)式 @type="unordered"
指定一個(gè)屬性名為 type
,其值為無序
。
表達(dá)式 h1[@ type="unordered"]
選擇所有 h1
元素其 type
屬性值是無序的。
假設(shè)我們將電話數(shù)據(jù)存儲(chǔ)在以下XML文檔中。
<PHONEBOOK> <PERSON> <NAME>Joe Wang</NAME> <EMAIL>joe@yourserver.com</EMAIL> <TELEPHONE>202-999-9999</TELEPHONE> <WEB>m.hgci.cn</WEB> </PERSON> <PERSON> <NAME>Karol</name> <EMAIL>karol@yourserver.com</EMAIL> <TELEPHONE>306-999-9999</TELEPHONE> <WEB>m.hgci.cn</WEB> </PERSON> <PERSON> <NAME>Green</NAME> <EMAIL>green@yourserver.com</EMAIL> <TELEPHONE>202-414-9999</TELEPHONE> <WEB>m.hgci.cn</WEB> </PERSON> </PHONEBOOK>
我們將使用以下XSLT將上述XML轉(zhuǎn)換為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>
從上面的代碼,我們可以看到數(shù)據(jù)將被轉(zhuǎn)換為HTML表。
我們使用下面的代碼來做轉(zhuǎn)換。
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解析器轉(zhuǎn)換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"))); } }
更多建議: