对大型xml字符串进行c#xslt转换会导致aspx超时



我正在使用.NET framework 4.5进行一个较旧的项目。有一个aspx页面包含通过服务器端调用完成的OnSelectedIndexChanged事件。服务器端调用使用一个返回xml的存储过程,然后使用转换将xml转换为html。问题是,当xml很大时(目前正在测试存储过程中的10k条xml格式的记录,尽管在生产中预期为100k条记录(,aspx页面就会超时。我不确定解决此问题的最佳方法是什么,因为executionTimeout的web.config设置设置非常高,debug设置为false。

Web.Config

<httpRuntime maxRequestLength="102400" executionTimeout="20000"/>

ASPX页面

<asp:DropDownList ID="ddlViews" runat="server" AutoPostBack="true" style="height:25px;min-width:150px;"  
OnSelectedIndexChanged="ddlViews_SelectedIndexChanged">
</asp:DropDownList>

。.

<asp:UpdatePanel ID="updPnl" runat="server">
<Triggers> 
<asp:AsyncPostBackTrigger ControlID="ddlViews" EventName="SelectedIndexChanged" />
</Triggers>
<ContentTemplate>
<asp:Literal ID="litData" runat="server"></asp:Literal>
</ContentTemplate>
</asp:UpdatePanel>

ASPX代码隐藏

protected void ddlViews_SelectedIndexChanged(object sender, EventArgs e)
{
if (ddlViews.Items.Count > 0 && ddlViews.SelectedValue != "-1")
{
System.Threading.Thread.Sleep(3000);
ShowView();
}
}
private void ShowView()
{
if (ddlViews.Items.Count > 0)
{
string inputXml = GetXml();
strData = Utils.ApplyXslt(inputXml);
litData.Text = strData;
}
}
public static string ApplyXslt(string xml)
{
try
{
string xsltUri = GetXslPath();
XsltArgumentList xslArg = new XsltArgumentList();
xslArg.AddExtensionObject("urn:string-plus", new XslStringPlus());
var xdoc = new XmlDocument();
xdoc.LoadXml(xml);
var xslt = new System.Xml.Xsl.XslCompiledTransform();
using (var mStream = new System.IO.MemoryStream())
{
xslt.Load(xsltUri);
xslt.Transform(xdoc, xslArg, mStream);
mStream.Position = 3;
var sr = new System.IO.StreamReader(mStream);
return sr.ReadToEnd();
}
}
catch (Exception e){
throw new Exception(String.Format("Error Applying Xslt from path '{0}'to xml value '{1}'", xsltUri, xml) + " | " + e.StackTrace);
}
}

完成10k记录的转换需要近3分钟。如果可能的话,能够大幅度减少这段时间将是一件很棒的事情。页面在1.5分钟后超时,我找不到任何能增加时间的东西。

XSLT

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xslplus="urn:string-plus">
<xsl:output method="html" />
<xsl:template match="/">
<table  id="tblLoanQuery" class="tableStyle">
<tr>
<xsl:for-each select="ROOT/Fields/child::*">
<xsl:variable name="h" select="." />
<th><xsl:value-of select="xslplus:FormatLabel($h)" /></th>
</xsl:for-each>
</tr>
<xsl:for-each select="ROOT/LoanNumbers/child::*">
<xsl:variable name="loanId" select="." />
<tr>
<xsl:for-each select="//ROOT/Fields/Field">
<xsl:variable name="fullFieldName" select="." />
<xsl:variable name="field" select="substring-after($fullFieldName,'.')" />
<xsl:variable name="FieldValue" select="//ROOT/ROWS/row[@lqKey=$loanId]/@*[name(.)= xslplus:ConvertSpace($field)]/." />
<td>
<xsl:value-of select="xslplus:FormatValue($FieldValue)"/>              
</td>
</xsl:for-each>
</tr>
</xsl:for-each>
</table>
</xsl:template>
</xsl:stylesheet>

在XSLT方面,//ROOT/ROWS/row[@lqKey=$loanId]似乎建议您使用密钥<xsl:key name="row-ref" match="ROOT/ROWS/row" use="@lqKey"/>并使用key('row-ref', $loanId)而不是//ROOT/ROWS/row[@lqKey=$loanId]。使用密钥可能会提高运行时性能。

最新更新