Quantcast
Viewing latest article 6
Browse Latest Browse All 55

Convert XML to HTML using XSLT in Java

In this post I will show you how to convert XML to HTML using XSLT in Java using Saxon HE version 11 library

We will add the dependency to our pom:

<dependency>
	<groupId>net.sf.saxon</groupId>
	<artifactId>Saxon-HE</artifactId>
	<version>11.5</version>
</dependency>

Our sample XML will be:

<detail>
  <product>
    <detail>Socket</detail>
    <brand>GM</brand>
    <models>
      <model>
        <model-no>123</model-no>
        <model-notes>Test</model-notes>
      </model>
      <model>
        <model-no>34</model-no>
        <model-notes>Test 2</model-notes>
      </model>
      <model>
        <model-no>56</model-no>
        <model-notes>Test 3</model-notes>
      </model>
      <model>
        <model-no>23</model-no>
        <model-notes>Test 4</model-notes>
      </model>
    </models>
  </product>
  <manufacturer>
    <country>
      <code>IN</code>
      <name>India</name>
    </country>
    <name>Philips Industries Ltd</name>
  </manufacturer>
</detail>

The XSLT we will be using to convert the XML into HTML is:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
	<xsl:output method="html" />
	<xsl:template match="detail">
		<div class="row">
			<div class="col">
				<h3>Details</h3>
				<form class="form-view">
					<div class="form-group row">
						<label for="" class="col-12 col-sm-4 col-lg-3 col-xl-2 col-form-label">Brand</label>
						<div class="col-12 col-sm-8 col-lg-3 col-xl-4">
							<span class="label-value"> <xsl:value-of select="product/brand"  /> </span>
						</div>
					</div>
					<div class="form-group row">
						<label for="" class="col-12 col-sm-4 col-lg-3 col-xl-2 col-form-label">Product</label>
						<div class="col-12 col-sm-8 col-lg-3 col-xl-4">
							<span class="label-value"><xsl:value-of select="product/detail"  /> </span>
						</div>
					</div>
					<div class="form-group row">
						<label for="" class="col-12 col-sm-4 col-lg-3 col-xl-2 col-form-label">Manufacturer</label>
						<div class="col-12 col-sm-8 col-lg-3 col-xl-4">
							<span class="label-value"><xsl:value-of select="manufacturer/name"  /> </span>
						</div>
						<label for="" class="col-12 col-sm-4 col-lg-3 col-xl-2 col-form-label">Manufactured In</label>
						<div class="col-12 col-sm-8 col-lg-3 col-xl-4">
							<span class="label-value">
								<xsl:value-of select="manufacturer/country/name"  />
							</span>
						</div>
					</div>
				</form><!-- End of .form-view -->
				<h3>Models</h3>
				<div class="table-responsive">
					<table class="table table-hover" border="0" cellpadding="0" cellspacing="0">
						<thead v-once="">
							<tr>
								<th width="30%">Model Number</th>
								<th width="70%">Notes</th>
							</tr>
						</thead>
						<tbody>
							<xsl:for-each select="product/models/model">
								<tr>
									<td data-label="Model Number"><xsl:value-of select="model-no" />  </td>
									<td data-label="Notes"><xsl:value-of select="model-notes" />  </td>
								</tr>
							</xsl:for-each>
						</tbody>
					</table>
				</div>
			</div><!-- End of .col -->
		</div><!-- End of .row -->
	</xsl:template><!-- detail template -->
	
	<xsl:template match="/">
    <html lang="en">
			<head>
				<meta charset="utf-8" />
				<meta name="viewport" content="width=device-width, initial-scale=1" />
				<title>XML to HTML</title>
				<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/css/bootstrap.min.css"
					rel="stylesheet" integrity="sha384-GLhlTQ8iRABdZLl6O3oVMWSktQOp6b7In1Zl3/Jr59b6EGGoI1aFkw7cmDA6j6gD"
					crossorigin="anonymous" />
			</head>
			<body>
				<div class="container">
				 <xsl:apply-templates />
				</div>
				<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/js/bootstrap.bundle.min.js"
					integrity="sha384-w76AqPfDkMBDXo30jS1Sgez6pr3x5MlQ1ZAGC+nuZB+EYdgRZgiwxhTBTkF7CXvN"
					crossorigin="anonymous"></script>
			</body>
    </html>
  </xsl:template>
</xsl:stylesheet>

Following are the steps to process the XML to HTML using Saxon library:

1. Create a new Processor instance. We are passing false because we are using the free edition of the library

Processor processor = new Processor(false);

2. Create a new Xslt30Transformer by loading the XSLT template to be used:

XsltCompiler xsltCompiler = processor.newXsltCompiler();
InputStream xsltStream = ClassLoader.getSystemResourceAsStream("sample-xslt2.xsl");
XsltExecutable xsltExecutable = xsltCompiler.compile(new StreamSource(xsltStream));
Xslt30Transformer xsltTransformer30 = xsltExecutable.load30();

In the above code we have placed our sample-xslt2.xsl at the root of the classpath. In our case it is the src/main/resources folder.

There are two XSLT transformers available:

  • XsltTransformer which is based on XSLT 2.0
  • Xslt30Transformer which is based on XSLT 3.0

Both of them have some differences at the XSLT W3C specification as well as some differences at the API level in the way we set the source XML and destination for HTML. We can get the XSLT 2.0 based transformer by invoking the method load() as shown below:

XsltTransformer xsltTransformer = xsltExecutable.load();

3. Initialize the destination for the XSLT transformer output:

We can write the output of the transformation to a file or to an output stream or to another XSLT Transformer. In our case we will write to a ByteArrayOutputStream. The place to which we write the output of the transformation is called as Destination here. So there are different imeplementations of Destination provided by the library and the one we will be using is called Serializer

If you are using Xslt30Transformer then you can create a new Serializer as shown below:

ByteArrayOutputStream arrayOutputStream = new ByteArrayOutputStream();
Serializer byteArrayOutput = xsltTransformer30.newSerializer(arrayOutputStream);

Or if you are using XsltTransformer then you can create a new Serializer using the Processor instance as shown below:

ByteArrayOutputStream arrayOutputStream = new ByteArrayOutputStream();
Serializer byteArrayOutput = processor.newSerializer(arrayOutputStream);

We will set some preferences for the output via the properties on the Serializer

byteArrayOutput.setOutputProperty(Serializer.Property.INDENT, "yes");
byteArrayOutput.setOutputProperty(Serializer.Property.METHOD, "html");
byteArrayOutput.setOutputProperty(Serializer.Property.OMIT_XML_DECLARATION, "yes");

4. Initialize the source XML to be processed

We will create an instance of StreamSource and point it to the input stream of the XML to be processed as shown below:

StreamSource streamSource = new StreamSource(ClassLoader.<em>getSystemResourceAsStream</em>("sample-xml2.xml"));

Finnally we invoke the transform() method of the Xslt30Transformer to process the XML and print out the contents from the ByteArrayOutputStream as shown below:

xsltTransformer30.transform(streamSource, byteArrayOutput);
System.out.println(arrayOutputStream.toString());

If you are using the XSLT 2.0 transformer i.e XsltTransformer then you need to set the source and destination and then invoke the transform() method as shown below:

xsltTransformer.setSource(streamSource);
xsltTransformer.setDestination(byteArrayOutput);
xsltTransformer.transform();

The HTML generated from this looks something like below:

Below is the complete code for processing based on Xslt30Transformer. You can also find the working code in the Github repo here.

public class App 
{
	public static void main( String[] args ) throws SaxonApiException, FileNotFoundException {
		Processor processor = new Processor(false);

		XsltCompiler xsltCompiler = processor.newXsltCompiler();
		InputStream xsltStream = ClassLoader.getSystemResourceAsStream("sample-xslt2.xsl");
		XsltExecutable xsltExecutable = xsltCompiler.compile(new StreamSource(xsltStream));
		Xslt30Transformer xsltTransformer30 = xsltExecutable.load30();


		ByteArrayOutputStream arrayOutputStream = new ByteArrayOutputStream();
		Serializer byteArrayOutput = processor.newSerializer(arrayOutputStream);
		byteArrayOutput.setOutputProperty(Serializer.Property.INDENT, "yes");
		byteArrayOutput.setOutputProperty(Serializer.Property.METHOD, "html");
		byteArrayOutput.setOutputProperty(Serializer.Property.OMIT_XML_DECLARATION, "yes");

		StreamSource streamSource = new StreamSource(
			ClassLoader.getSystemResourceAsStream("sample-xml2.xml"));
		xsltTransformer30.transform(streamSource, byteArrayOutput);
		System.out.println(arrayOutputStream.toString());

	}
}

The post Convert XML to HTML using XSLT in Java appeared first on Experiences Unlimited.


Viewing latest article 6
Browse Latest Browse All 55

Trending Articles