Tengo un marco que genera el XML, en función de la solicitud HTTP y el estado de la sesión actual. Puedo probar en HTML, pero la salida de producción será VXML, quizás uno o dos "sabores" por diferentes razones.Quiero mejorar el rendimiento de xslt
Aquí está la parte lenta de mi HttpServlet:
jsp InputStream ms = new java.io.ByteArrayInputStream(sb.toString().getBytes());
Source xmlSource = new javax.xml.transform.stream.StreamSource(ms);
String filePath = getServletContext().getRealPath(("/GetNextEvent-").
concat(req.getSession().getAttribute("client").toString().toUpperCase()).concat(".xsl"));
Source xsltSource = new javax.xml.transform.stream.StreamSource(filePath);
Result result = new javax.xml.transform.stream.StreamResult(resp.getWriter());
TransformerFactory tf = TransformerFactory.newInstance();
Transformer t = tf.newTransformer(xsltSource);
t.transform(xmlSource, result);
lleva este momento ~ 200 ms. Me gustaría que sea mucho más rápido. ¿Quizás < 10ms?
- Sugerencias para almacenar en caché? - Al ver que los archivos xsl permanecen iguales durante todo el despliegue, los objetos de Transformer se pueden almacenar en caché de forma indefinida. Estoy pensando en almacenarlo en caché en el nivel de la sesión, por lo que cada sesión (1000 simultánea) tiene la suya. ¿Alguna sugerencia? ¿Debería usar algún framework para el almacenamiento en caché, por algún motivo?
- ¿Hay una forma más rápida de transformar el xml en el flujo de respuesta?
- ¿Debo eliminar esto e ir a otra ruta? Si notó el sb.toString, estoy usando un StringBuilder para obtener la representación XML de los objetos (los objetos usan un generador de cadenas para crear cadenas XML). Se tarda aproximadamente 1 milisegundo en crear el documento XML utilizando StringBuilders, por lo que no me preocupa en este momento.
Editar:
Aquí está el documento XSL. El documento XML suele ser muy pequeño. Solo un par de elementos. XML de ejemplo está por debajo de XSL:
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:regexp="http://exslt.org/regular-expressions"
xmlns:str="http://exslt.org/strings" xmlns:twc="http://twc.com/2009/01/ivr/framework"
exclude-result-prefixes="twc regexp str" extension-element-prefixes="str">
<xsl:output method="xml" encoding="ISO-8859-1" />
<xsl:template match="/">
<vxml xmlns="http://www.w3.org/2001/vxml" version="2.1" xml:lang="en-US"
application="root.xml">
<xsl:attribute name="xml:lang"><xsl:value-of
select="//twc:response/@language" /></xsl:attribute>
<form id="ivrFramework">
<var name="logDebug">
<xsl:attribute name="expr"><xsl:value-of
select="//twc:response/@debug" /></xsl:attribute>
</var>
<var name="event" expr="'OK'" />
<var name="lastResult" expr="''" />
<var name="lastResultMode" expr="''" />
<var name="lastResultValue" expr="''" />
<var name="srConfidence" expr="'1000'" />
<xsl:apply-templates select="//twc:command" />
<xsl:if test="count(//twc:command)=0">
<block>
<log cond="logDebug" expr="'No more commands. Exiting.'" />
<exit />
</block>
</xsl:if>
</form>
</vxml>
</xsl:template>
<xsl:template
match="twc:command[@type='prompt' and contains(text(), 'TransferDialog')]">
<transfer name="quicktransfer" type="consultation">
<xsl:attribute name="destexpr"><xsl:choose>
<xsl:when test="//twc:parameter[twc:name='destination']">'<xsl:value-of
select="//twc:parameter[twc:name='destination']/twc:value" />'</xsl:when>
<xsl:otherwise>'tel:1136300'</xsl:otherwise>
</xsl:choose>
</xsl:attribute>
<xsl:if test="//twc:parameter[twc:name='initial']">
<prompt>
<xsl:call-template name="process_prompt">
<xsl:with-param name="prompt_type" select="'initial'" />
</xsl:call-template>
</prompt>
</xsl:if>
</transfer>
</xsl:template>
<xsl:template
match="twc:command[@type='prompt' and contains(text(), 'BasicDialog')]">
<xsl:choose>
<xsl:when test="//twc:parameter[twc:name='grammar']/twc:value">
<field>
<xsl:attribute name="name"><xsl:value-of
select="//twc:parameter[twc:name='variable']/twc:value" /></xsl:attribute>
<noinput count="3">
<assign name="event" expr="'noinput'" />
<submit next="GetNextEvent2.jsp"
namelist="event lastResult lastResultMode lastResultValue srConfidence" />
</noinput>
<nomatch count="3">
<assign name="event" expr="'invalid'" />
<submit next="GetNextEvent2.jsp"
namelist="event lastResult lastResultMode lastResultValue srConfidence" />
</nomatch>
<xsl:for-each select="//twc:parameter[twc:name='grammar']/twc:value">
<grammar>
<xsl:attribute name="src"><xsl:if test="//twc:response/@base!=''"><xsl:value-of select="//twc:response/@base" /></xsl:if><xsl:value-of
select="." /></xsl:attribute>
</grammar>
</xsl:for-each>
<xsl:if test="//twc:parameter[twc:name='help']">
<help>
<xsl:call-template name="process_prompt">
<xsl:with-param name="prompt_type" select="'help'" />
</xsl:call-template>
</help>
</xsl:if>
<xsl:if test="//twc:parameter[twc:name='noinput1']">
<noinput count="1">
<xsl:call-template name="process_prompt">
<xsl:with-param name="prompt_type" select="'noinput1'" />
</xsl:call-template>
</noinput>
</xsl:if>
<xsl:if test="//twc:parameter[twc:name='noinput2']">
<noinput count="2">
<xsl:call-template name="process_prompt">
<xsl:with-param name="prompt_type" select="'noinput2'" />
</xsl:call-template>
</noinput>
</xsl:if>
<xsl:if test="//twc:parameter[twc:name='invalid1']">
<nomatch count="1">
<xsl:call-template name="process_prompt">
<xsl:with-param name="prompt_type" select="'invalid1'" />
</xsl:call-template>
</nomatch>
</xsl:if>
<xsl:if test="//twc:parameter[twc:name='invalid2']">
<nomatch count="2">
<xsl:call-template name="process_prompt">
<xsl:with-param name="prompt_type" select="'invalid2'" />
</xsl:call-template>
</nomatch>
</xsl:if>
<xsl:if test="//twc:parameter[twc:name='initial']">
<prompt>
<xsl:call-template name="process_prompt">
<xsl:with-param name="prompt_type" select="'initial'" />
</xsl:call-template>
</prompt>
</xsl:if>
<filled>
<log cond="logDebug" expr="'Filled.'" />
<assign name="event" expr="'OK'" />
<assign name="lastResult" expr="application.lastresult$.utterance" />
<assign name="lastResultMode" expr="application.lastresult$.inputmode" />
<assign name="lastResultValue" expr="application.lastresult$.interpretation" />
<assign name="srConfidence" expr="application.lastresult$.confidence " />
<submit next="GetNextEvent2.jsp"
namelist="event lastResult lastResultMode lastResultValue srConfidence" />
</filled>
</field>
</xsl:when>
<xsl:when test="//twc:parameter[twc:name='initial']/twc:value">
<block>
<xsl:if test="//twc:parameter[twc:name='initial']">
<prompt>
<xsl:call-template name="process_prompt">
<xsl:with-param name="prompt_type" select="'initial'" />
</xsl:call-template>
</prompt>
</xsl:if>
<submit next="GetNextEvent2.jsp"
namelist="event lastResult lastResultMode lastResultValue srConfidence" />
</block>
</xsl:when>
<xsl:otherwise>
<block>
<log cond="logDebug" expr="'Didn't find values for grammar or initial. Exiting.'" />
<exit />
</block>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template name="process_prompt">
<xsl:param name="prompt_type" />
<xsl:for-each select="//twc:parameter[twc:name=$prompt_type]/twc:value">
<xsl:if test="contains(., '::')">
<audio>
<xsl:for-each select="str:split(., '::')">
<xsl:if test="position()=1">
<xsl:attribute name="src"><xsl:if test="//twc:response/@base!=''"><xsl:value-of select="//twc:response/@base" /></xsl:if><xsl:value-of
select="." /></xsl:attribute>
</xsl:if>
<xsl:if test="position()=2">
<xsl:value-of select="." />
</xsl:if>
</xsl:for-each>
</audio>
</xsl:if>
<xsl:if test="contains(., 'Date:')">
<say-as interpret-as="date" format="ymd">
<xsl:for-each select="str:split(., ':')">
<xsl:if test="position()=2">
<xsl:value-of select="." />
</xsl:if>
</xsl:for-each>
</say-as>
</xsl:if>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
He aquí algunos XML:
<?xml version="1.0"?>
<response xmlns="http://twc.com/2009/01/ivr/framework" language="en-us" debug="true"
base="/IVRFrameworkResources/Outage/">
<command type="prompt"> BasicDialog <parameter>
<name>initial</name>
<value>en-us/prompts/OutageCleared.wav::Hello. I'm letting you know the
incident that caused your outage has been fixed. </value>
</parameter>
</command>
</response>
¿Puede mostrarnos su XSLT con un documento de entrada de muestra? Es posible que su XSLT contenga consultas ineficaces que pueden optimizarse (las consultas ineficientes se pueden crear en casi cualquier lenguaje de consulta por cierto, por lo que culpar a XLST por ser lento generalmente no es justo). –
Adjuntaré XSLT, pero quizás esa sea otra pregunta :) – ericp
¿Puede mostrar el documento * input * también? Eso importa más que la salida. –