Java XSLT

2018-02-12 19:40 更新

Java XML教程 - Java XSLT


可擴(kuò)展樣式表語言轉(zhuǎn)換(XSLT)標(biāo)準(zhǔn)定義類,用于使用XPath尋址XML數(shù)據(jù)和進(jìn)行轉(zhuǎn)換數(shù)據(jù)以其他形式。

JAXP包括XSLT的解釋實(shí)現(xiàn)。

XSL,XSLT和XPath

可擴(kuò)展樣式表語言(XSL)有三個(gè)主要子組件:

組件描述
XSL-FO格式化對(duì)象標(biāo)準(zhǔn)。 我們可以定義字體大小,頁面布局和對(duì)象呈現(xiàn)的其他方面。
XSLT它定義了從XML到其他格式的轉(zhuǎn)換。例如,使用XSLT從XML文檔生成HTML。
XPathXPath是一種規(guī)范語言,我們可以用它來創(chuàng)建一個(gè)元素的路徑。

JAXP轉(zhuǎn)換包

以下是對(duì)JAXP Transformation API的包的描述:

描述
javax.xml.transform這個(gè)包定義了返回Transformer對(duì)象的工廠類。 我們可以使用輸入和輸出對(duì)象配置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):


  • 元素
  • 文本
  • 屬性
  • 注釋
  • 處理指令
  • 命名空間

XPath尋址

XML文檔是樹結(jié)構(gòu)的節(jié)點(diǎn)集合。

XPath使用路徑符號(hào)在XML中尋址節(jié)點(diǎn)。

  • 正斜杠/是路徑分隔符。
  • 文檔根目錄的絕對(duì)路徑以/開頭。
  • 相對(duì)路徑可以從任何其他開始。
  • 雙重周期..表示父節(jié)點(diǎn)。
  • 單個(gè)期間.表示當(dāng)前節(jié)點(diǎn)。

在XPath /h1/h2 中選擇位于h1元素下的所有h2元素。

要選擇一個(gè)特定的h2元素,我們使用方括號(hào) [] 來索引。

例如, /h1[4]/h2 [5] 將選擇第五個(gè) h2 在第四個(gè) h1 元素下。

要引用屬性,請(qǐng)?jiān)趯傩悦Q前加上@符號(hào)。例如, @type 是指 type 屬性。

h1/@type選擇 h1 元素的 type 屬性。


XPath表達(dá)式

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>o2fo.com</WEB>
</PERSON>
<PERSON>
 <NAME>Karol</name>
 <EMAIL>karol@yourserver.com</EMAIL>
 <TELEPHONE>306-999-9999</TELEPHONE>
 <WEB>o2fo.com</WEB>
</PERSON>
<PERSON>
 <NAME>Green</NAME>
 <EMAIL>green@yourserver.com</EMAIL>
 <TELEPHONE>202-414-9999</TELEPHONE>
 <WEB>o2fo.com</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);
  }
}

例2

以下代碼顯示了如何使用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;
  }

}

例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")));
  }
}
以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)