Java XSLT

2018-02-12 19:40 更新

Java XML教程 - Java XSLT


可扩展样式表语言转换(XSLT)标准定义类,用于使用XPath寻址XML数据和进行转换数据以其他形式。

JAXP包括XSLT的解释实现。

XSL,XSLT和XPath

可扩展样式表语言(XSL)有三个主要子组件:

组件描述
XSL-FO格式化对象标准。 我们可以定义字体大小,页面布局和对象呈现的其他方面。
XSLT它定义了从XML到其他格式的转换。例如,使用XSLT从XML文档生成HTML。
XPathXPath是一种规范语言,我们可以用它来创建一个元素的路径。

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")));
  }
}
以上内容是否对您有帮助:
在线笔记
App下载
App下载

扫描二维码

下载编程狮App

公众号
微信公众号

编程狮公众号