Hello and thank you for reading this question:
I am studying Enterprise Architecture Patterns and I have implemented the Transform View one:
Java: Implementing Transform View pattern, to convert XML to HTML with an XSL file
First, in the first 10 slides, I will describe what have I learnt, then an example taken from books and finally the approach I have tryed to implement it by myself, and the doubts I have with the Java code:
I have studied how is it described in UML, an example would be, (images taken from teacher's lessons):
We have an album which is read and then converted to an intermediate format and then it is being process in a generic way:
In more details if we have a Shop Page, each Order would have Line Items and those being transformed to our format file: Order First Stage. Then the generated Table with its rows would being translated to the HTML without knowing where it comes from:
So then it means that the controller creates our order first stage, our format file. Then, we get the Order Data and the Line Item data to create our new Table with its Rows. After that the Controller creates the Second Stage, which gets the Table and Row, and add them both to response HTML:
The reason we are interested in learning this pattern, is because of it is a handy way to convert in a single spot all our web app's style:
In the previous slide we see how we would only need to change Second Stage XSL file to display a new style in all our app's pages.
In deep, we could interchange whatever new XSL and thus app's styles we would like to put in production:
As an example extracted from books, here we see an album:
So the First Stage XSL would convert album's XML tags to an intermediate format, with has more generic tags like: screen, table, row...
After the above transformation the output XML would be:
In addition as we are interested in process the generic XML using a single spot the Second Stage:
After all the previous steps we eventually need to implement the logic in Java, and as the example gives us a clue it would look like:
So then, I tried the following:
First here we have the XML which represents ficticious pupils' info:
<?xml version="1.0"?>
<ALUMNO>
<NOMBRE>Luis</NOMBRE>
<APELLIDO1>Navarro</APELLIDO1>
<APELLIDO2>Morote</APELLIDO2>
<ASIGNATURAS>
<ASIGNATURA>PR4</ASIGNATURA>
<NOTA>5</NOTA>
<ASIGNATURA>BD2</ASIGNATURA>
<NOTA>8</NOTA>
<ASIGNATURA>IR</ASIGNATURA>
<NOTA>10</NOTA>
</ASIGNATURAS>
</ALUMNO>
Then we do the First Stage XSL to convert pupils' tags in an intermediate file format:
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet
xmlns:xsl=
"http://www.w3.org/1999/XSL/Transform"
version="1.0"
>
<xsl:template match="ALUMNO">
<table>
<xsl:apply-template/>
</table>
</xsl:template>
<xsl:template match="NOMBRE">
<firstCell>
<xsl:apply-templates/>
</firstCell>
</xsl:template>
<xsl:template match="APPELLIDO1">
<secondCell>
<xsl:apply-templates/>
</secondCell>
</xsl:template>
<xsl:template match="APPELLIDO2">
<thirdCell>
<xsl:apply-templates/>
</thirdCell>
</xsl:template>
<xsl:template match="ASIGNATURA">
<fourthCell>
<xsl:apply-templates/>
</fourthCell>
</xsl:template>
<xsl:template match="NOTA">
<fifthCell>
<xsl:apply-templates/>
</fifthCell>
</xsl:template>
</xsl:stylesheet>
After the previous step, we process with the Second Stage the generic tags to style the way we want, as a table:
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet
xmlns:xsl=
"http://www.w3.org/1999/XSL/Transform"
version="1.0"
>
<xsl:template match="/">
<html>
<head>
<title>LISTA DE ALUMNOS</title>
</head>
<body bgColor="black" text="white">
<table>
<tr>
<th colspan="4">Nombre</th>
<th colspan="3">Primer apellido</th>
<th colspan="3">Segundo apellido</th>
<th colspan="2">Asignatura</th>
<th colspan="2">Nota</th>
</tr>
<xsl:apply-templates />
</table>
</body>
</html>
</xsl:template>
<xsl:template match="table">
<tr>
<td colspan="4">
<xsl:value-of select="firstCell" />
</td>
<td colspan="3">
<xsl:value-of select="secondCell" />
</td>
<td colspan="3">
<xsl:value-of select="thirdCell" />
</td>
<td colspan="2">
<xsl:value-of select="fourthCell" />
</td>
<td colspan="2">
<xsl:value-of select="fifthCell" />
</td>
</tr>
</xsl:template>
<xsl:template match="firstCell">
<P>
<B>Nombre: </B>
<TR>
<xsl:apply-templates/>
</TR>
</P>
</xsl:template>
<xsl:template match="fourthCell">
<h1>Aginatura: </h1>
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="fifthCell">
<h2>Nota: </h2>
<xsl:apply-templates/>
</xsl:template>
<xsl:output method="html"/>
</xsl:stylesheet>
Now here arrives our doubt: How could we transform the Result of transforming the original XML with the First Stage's XSL, using the Second Stage's XSL to output our desired HTML?.
I have tried:
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package frontController;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.xml.transform.Result;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
/**
*
* @author YonePC
*/
@WebServlet(name = "AlumnosCommand", urlPatterns = {"/AlumnosCommand"})
public class AlumnosCommand extends FrontCommand {
/**
* Processes requests for both HTTP <code>GET</code> and <code>POST</code>
* methods.
*
* @param request servlet request
* @param response servlet response
* @throws ServletException if a servlet-specific error occurs
* @throws IOException if an I/O error occurs
*/
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
}
// <editor-fold defaultstate="collapsed" desc="HttpServlet methods. Click on the + sign on the left to edit the code.">
/**
* Handles the HTTP <code>GET</code> method.
*
* @param request servlet request
* @param response servlet response
* @throws ServletException if a servlet-specific error occurs
* @throws IOException if an I/O error occurs
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
processRequest(request, response);
}
/**
* Handles the HTTP <code>POST</code> method.
*
* @param request servlet request
* @param response servlet response
* @throws ServletException if a servlet-specific error occurs
* @throws IOException if an I/O error occurs
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
processRequest(request, response);
}
/**
* Returns a short description of the servlet.
*
* @return a String containing servlet description
*/
public String getServletInfo() {
return "Short description";
}// </editor-fold>
@Override
public void process(HttpServletRequest request) {
try {
TransformerFactory factory = TransformerFactory.newInstance();
StreamSource xslFirstStage = new StreamSource(new File("C:\\Users\\YonePC\\Videos\\ASAPLICACIONCURSOSPRACTICA1\\src\\java\\frontController\\FirstStageAlumnos.xsl"));
StreamSource xslSecondStage = new StreamSource(new File("C:\\Users\\YonePC\\Videos\\ASAPLICACIONCURSOSPRACTICA1\\src\\java\\frontController\\Alumnos.xsl"));
Transformer firstTransformer = factory.newTransformer(xslFirstStage);
Transformer secondTransformer = factory.newTransformer(xslSecondStage);
StreamSource xml = new StreamSource(new File("C:\\Users\\YonePC\\Videos\\ASAPLICACIONCURSOSPRACTICA1\\src\\java\\frontController\\Alumnos.xml"));
PrintWriter writer = response.getWriter();
Result result = new StreamResult(writer);
OutputStream afterFirstStage = new FileOutputStream("C:\\Users\\YonePC\\Videos\\ASAPLICACIONCURSOSPRACTICA1\\src\\java\\frontController\\afterFirstStage.xsl");
firstTransformer.transform(xml, new StreamResult(afterFirstStage));
secondTransformer.transform(afterFirstStage, xslSecondStage);
writer.println(writer.toString());
} catch (IOException ioe) {
ioe.printStackTrace();
} catch (TransformerException te) {
te.printStackTrace();
}
}
}
As the IDE says when we use Transformer.transform() first parameter should be a Source and second a StreamSource.
Here the IDE says: incompatible types: cannot convert OutputStream to Source.
Could you help me please?
I have also read to do it by myself: How to convert XML to HTML using XSLT in Java
http://www.javased.com/index.php?api=javax.xml.transform.Result