【问题标题】:JAVA: Two Step View Pattern: How could we convert a Transform View to a Two Steps View using two XSL files to get the desired HTML output?‽JAVA:两步视图模式:我们如何使用两个 XSL 文件将转换视图转换为两步视图以获得所需的 HTML 输出?‽
【发布时间】:2018-08-04 21:17:52
【问题描述】:

您好,感谢您阅读此问题:

我正在研究企业架构模式,我已经实现了转换视图:

Java: Implementing Transform View pattern, to convert XML to HTML with an XSL file

首先,在前 10 张幻灯片中,我将描述我学到了什么,然后是从书本上摘录的示例,最后是我尝试自己实现它的方法,以及我对 Java 代码的疑问:

我研究过 UML 是如何描述它的,例如,(图片取自老师的课程):

我们有一张专辑被读取,然后转换为中间格式,然后以通用方式处理:

更详细地说,如果我们有一个商店页面,每个订单都会有订单项,并且这些订单项将被转换为我们的格式文件:订单第一阶段。然后生成的 Table 及其行将被翻译成 HTML,而不知道它来自哪里:

那么这意味着控制器创建我们的订单第一阶段,我们的格式文件。然后,我们获取订单数据和行项目数据来创建带有行的新表。之后,控制器创建第二阶段,它获取表和行,并将它们都添加到响应 HTML:

我们之所以对学习这种模式感兴趣,是因为它是一种在一个地方转换我们所有网络应用程序样式的便捷方式:

在上一张幻灯片中,我们看到了如何只需要更改 Second Stage XSL 文件即可在我们所有应用的页面中显示新样式。

深入地讲,我们可以互换任何新的 XSL 以及我们想要投入生产的应用样式:

作为从书籍中提取的示例,这里我们看到一张专辑:

因此,First Stage XSL 会将专辑的 XML 标签转换为中间格式,具有更通用的标签,例如:屏幕、表格、行...

经过上述转换后,输出 XML 将是:

此外,我们有兴趣在第二阶段使用单个位置处理通用 XML:

在完成所有前面的步骤之后,我们最终需要在 Java 中实现逻辑,并且作为示例给我们提供了一个线索,它看起来像这样:

那么,我尝试了以下方法:

首先,这里有代表虚构学生信息的 XML:

<?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>

然后我们做第一阶段的XSL,将学生的标签转换成中间文件格式:

<?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>

在上一步之后,我们在第二阶段处理通用标签以按照我们想要的方式设置样式,作为表格:

<?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>

现在我们的疑问出现了:我们如何使用 First Stage 的 XSL 转换原始 XML 的 Result,使用 Second Stage 的 XSL 来输出我们想要的 HTML?。强>

我试过了:

/*
 * 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();

        }
    }

}

正如 IDE 所说,当我们使用 Transformer.transform() 时,第一个参数应该是 Source,第二个参数应该是 StreamSource。

这里 IDE 说:不兼容的类型:无法将 OutputStream 转换为 Source。

你能帮帮我吗?

我自己也读过:How to convert XML to HTML using XSLT in Java

http://www.javased.com/index.php?api=javax.xml.transform.Result

【问题讨论】:

    标签: java html xml jsp xslt


    【解决方案1】:

    如果您想使用中间文件,那么您当然需要在第一次转换后关闭该输出流,并在您创建的文件上打开一个新的StreamSource,然后将其用作第二次转换的输入.

    使用基于 JAXP 和 SAX 的转换器,您可以避免使用中间文件,而只需设置一些处理程序 (https://docs.oracle.com/javase/8/docs/api/javax/xml/transform/sax/SAXTransformerFactory.html),例如

    TransformerHandler tfh = (SAXTransformerFactory)transformerFactory.newInstance().newTransformer(new StreamSource("second.xsl"));
    tfh.setResult(new StreamResult("finalOutput.xml"));
    
    firstTransformer.transform(inputSource, new SAXResult(tfh));
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-11-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多