杰瑞科技汇

Java如何用XSLT实现XML到XML转换?

Of course! Transforming one XML file into another using XSLT in Java is a very common task. The standard Java API for this is the javax.xml.transform package, which has been part of Java since version 1.4.

Java如何用XSLT实现XML到XML转换?-图1
(图片来源网络,侵删)

Here’s a complete guide, from a simple example to a more detailed explanation of the components and best practices.

The Core Concept

The process involves three main components:

  1. Source XML: The input XML document you want to transform.
  2. XSLT Stylesheet: A set of rules (written in XSLT) that defines how to transform the source XML into the desired output.
  3. Result XML: The output document generated by applying the stylesheet to the source.

Java's Transformer class acts as the engine that performs this transformation.


Step-by-Step Example

Let's create a practical example. We'll transform a simple list of books into a different XML structure.

Java如何用XSLT实现XML到XML转换?-图2
(图片来源网络,侵删)

The Source XML (books.xml)

This file contains our raw data.

<!-- books.xml -->
<catalog>
    <book id="bk101">
        <author>Gambardella, Matthew</author>
        <title>XML Developer's Guide</title>
        <genre>Computer</genre>
        <price>44.95</price>
        <publish_date>2000-10-01</publish_date>
    </book>
    <book id="bk102">
        <author>Ralls, Kim</author>
        <title>Midnight Rain</title>
        <genre>Fantasy</genre>
        <price>5.95</price>
        <publish_date>2000-12-16</publish_date>
    </book>
    <book id="bk103">
        <author>Corets, Eva</author>
        <title>Maeve Ascendant</title>
        <genre>Fantasy</genre>
        <price>5.95</price>
        <publish_date>2000-11-17</publish_date>
    </book>
</catalog>

The XSLT Stylesheet (transform_books.xslt)

This file defines the transformation rules. We will:

  • Change the root element from <catalog> to <library>.
  • Rename <book> to <volume>.
  • Reorder and rename some elements.
  • Format the price to include a currency symbol.
<!-- transform_books.xslt -->
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" indent="yes" omit-xml-declaration="no" encoding="UTF-8"/>
    <!-- Identity transform: copies all nodes and attributes by default -->
    <xsl:template match="@* | node()">
        <xsl:copy>
            <xsl:apply-templates select="@* | node()"/>
        </xsl:copy>
    </xsl:template>
    <!-- Override the root element -->
    <xsl:template match="/catalog">
        <library>
            <xsl:apply-templates select="book"/>
        </library>
    </xsl:template>
    <!-- Override the book element -->
    <xsl:template match="book">
        <volume id="{@id}">
            <xsl:apply-templates select="title"/>
            <xsl:apply-templates select="author"/>
            <xsl:apply-templates select="price"/>
            <xsl:apply-templates select="genre"/>
        </volume>
    </xsl:template>
    <!-- Override the price element to add a currency symbol -->
    <xsl:template match="price">
        <cost currency="USD">
            <xsl:value-of select="concat('$', .)"/>
        </cost>
    </xsl:template>
    <!-- You can also add new elements or remove them by simply not having a template -->
    <!-- For example, this template would remove all publish_date elements -->
    <xsl:template match="publish_date"/>
</xsl:stylesheet>

The Java Code (XmlTransformer.java)

This is the Java class that performs the transformation.

// XmlTransformer.java
import javax.xml.transform.*;
import javax.xml.transform.stream.*;
import java.io.*;
public class XmlTransformer {
    public static void main(String[] args) {
        // 1. Define the source XML file and the XSLT stylesheet
        File sourceXml = new File("books.xml");
        File xsltFile = new File("transform_books.xslt");
        // 2. Define the output file for the transformed XML
        File resultXml = new File("library.xml");
        try {
            // 3. Create a factory for the TransformerFactory
            TransformerFactory factory = TransformerFactory.newInstance();
            // 4. Create a Transformer from the XSLT stylesheet
            Transformer transformer = factory.newTransformer(new StreamSource(xsltFile));
            // You can also set output properties here if needed
            // transformer.setOutputProperty(OutputKeys.INDENT, "yes");
            // transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
            // 5. Perform the transformation
            // The transform method takes the source XML and writes the result to the output file
            transformer.transform(new StreamSource(sourceXml), new StreamResult(resultXml));
            System.out.println("XML transformation complete. Result saved to " + resultXml.getAbsolutePath());
        } catch (TransformerException e) {
            // Handle any transformation errors
            System.err.println("Error during transformation: " + e.getMessage());
            e.printStackTrace();
        } catch (Exception e) {
            // Handle other potential I/O errors
            e.printStackTrace();
        }
    }
}

The Result XML (library.xml)

After running the Java program, this file will be generated:

Java如何用XSLT实现XML到XML转换?-图3
(图片来源网络,侵删)
<!-- library.xml -->
<?xml version="1.0" encoding="UTF-8"?>
<library>
   <volume id="bk101">
      <title>XML Developer's Guide</title>
      <author>Gambardella, Matthew</author>
      <cost currency="USD">$44.95</cost>
      <genre>Computer</genre>
   </volume>
   <volume id="bk102">
      <title>Midnight Rain</title>
      <author>Ralls, Kim</author>
      <cost currency="USD">$5.95</cost>
      <genre>Fantasy</genre>
   </volume>
   <volume id="bk103">
      <title>Maeve Ascendant</title>
      <author>Corets, Eva</author>
      <cost currency="USD">$5.95</cost>
      <genre>Fantasy</genre>
   </volume>
</library>

Detailed Breakdown of the Java Code

TransformerFactory

This is the entry point for the API. It's a factory class used to create Transformer instances.

  • TransformerFactory.newInstance(): This static method locates and instantiates a TransformerFactory implementation. The underlying implementation is determined by system properties or the JAR files available on the classpath.

Transformer

This is the core engine that performs the transformation. It's created from the TransformerFactory by loading an XSLT stylesheet.

  • factory.newTransformer(new StreamSource(xsltFile)): This method loads the stylesheet from the specified file (xsltFile) and prepares the transformer to use its rules.

StreamSource and StreamResult

These are helper classes that allow you to use I/O streams (like files or network connections) as the source or destination for the transformation.

  • StreamSource: Represents an input source, like our books.xml. It can be created from a File, InputStream, or Reader.
  • StreamResult: Represents an output result, like our library.xml. It can be created from a File, OutputStream, or Writer.

transformer.transform(...)

This is the method that executes the transformation.

  • It takes two arguments:
    1. Source source: The input XML (StreamSource for books.xml).
    2. Result output: The destination for the transformed XML (StreamResult for library.xml).

Handling Different Input/Output Sources

You are not limited to files. Here's how you can use other sources:

From a String to a String

Use StringReader and StringWriter.

// Assuming 'xmlString' and 'xsltString' contain your XML and XSLT
String xmlString = "<root><item>hello</item></root>";
String xsltString = "<xsl:stylesheet version='1.0' xmlns:xsl='http://www.w3.org/1999/XSL/Transform'><xsl:template match='/root'><output><xsl:value-of select='item'/></output></xsl:template></xsl:stylesheet>";
StringWriter writer = new StringWriter();
Transformer transformer = factory.newTransformer(new StreamSource(new StringReader(xsltString)));
transformer.transform(new StreamSource(new StringReader(xmlString)), new StreamResult(writer));
String resultString = writer.toString();
System.out.println(resultString);

From a URL to a File

Use URL objects for the source.

// Assuming 'xsltFile' is already defined
URL xmlUrl = new URL("
分享:
扫描分享到社交APP
上一篇
下一篇