c# xslt transform on large xml string causes aspx timeout

c# xslt transform on large xml string causes aspx timeout

我正在使用 .NET Framework 4.5 处理一个较旧的项目。有一个带有 OnSelectedIndexChanged 事件的 aspx 页面,该事件通过服务器端调用完成。服务器端调用使用 returns xml 的存储过程,然后使用转换将 xml 转换为 html。问题是,当 xml 很大时(当前使用存储过程中 xml 格式的 10k 条记录进行测试,尽管生产中的预期是 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]。使用密钥可能会提高 运行 时间性能。