У меня есть структура, которая генерирует XML на основе HTTP-запроса и текущего состояния сеанса. Я могу протестировать в HTML, но производственный вывод будет VXML - возможно, один или два «варианта» по разным причинам.
Вот медленная часть моего 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);
В настоящее время это занимает ~ 200 мс. Я бы хотел, чтобы это было намного быстрее. Возможно, <10 мс? </p>
- Предложения по кешированию? - видя, что файлы xsl остаются неизменными на протяжении всего развертывания, объекты Transformer могут кэшироваться бесконечно. Я думаю о кешировании на уровне сеанса, поэтому каждый сеанс (1000 сеансов) имеет свой. Какие-либо предложения? Должен ли я использовать какие-либо рамки для кэширования, по любой причине?
- Есть ли более быстрый способ преобразования xml в поток ответов?
- Должен ли я отказаться от этого и пойти другим путем? Если вы заметили sb.toString, я использую StringBuilder для получения XML-представления объектов (объекты используют строитель строк для создания строки XML). Создание XML-документа с использованием StringBuilders занимает около 1 миллисекунды, поэтому в данный момент меня это не беспокоит.
Edit:
Вот документ XSL. XML-документ обычно очень маленький. Просто пара элементов. Пример XML ниже 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>
Вот немного 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>