c# - c# xslt 对大 xml 字符串的转换导致 aspx 超时
问题描述
我正在使用 .NET 框架 4.5 处理一个较旧的项目。有一个带有 OnSelectedIndexChanged 事件的 aspx 页面,该事件通过服务器端调用完成。服务器端调用使用返回 xml 的存储过程,然后使用转换将 xml 转换为 html。问题是,当 xml 很大时(当前使用存储的 proc 中的 xml 格式的 10k 记录进行测试,尽管生产中的预期是 100k 记录),然后 aspx 页面超时。我不确定解决此问题的最佳方法是什么,因为 executionTimeout 的 web.config 设置设置得非常高,并且 debug 设置为 false。
网络配置
<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 条记录,Transform 需要近 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]
. 使用密钥可能会提高运行时性能。
推荐阅读
- ffmpeg - 某些视频无法通过错误 MEDIA_UNKNOWN 进行 chromecast
- javascript - 黑客如何滥用 javascript 的 eval() 进行跨站攻击?
- php - PHP foreach 语句拆分名称 MySQL 数据库
- compilation - 如何为 Debian 9 编译 linphone 3.12.0?
- android - How to intertwine Async functions and sync functions in flutter
- corda - 使用 SSH 连接到 Corda Explorer UI 时出现以下错误“PortForwardingL:local port 127.0.0.1:10005 can't be bound”
- sql - 我需要关于密码生成器 python 脚本的建议
- jms - 将消息从 BackOut 队列移动到主队列
- sql - 通过获取同一分区中的上一个日期进行分区
- c - 使用结构数组和文件通过函数传递值