6

尝试加载 XSLT 样式表时出现异常。XSLT 样式表非常大(几乎 8,000 行)。不幸的是,我对此没有任何控制权,我无法重构样式表以使其更小。

我们最近升级到 .Net Framework 4.5。以下命令在升级之前运行良好(我们使用的是 .Net Framework 4.0)。升级后,我们收到一条XsltException“样式表太复杂”的transform.Load在线信息。

我希望有一些新设置会说“让这个命令像在 4.0 中那样工作”,但我在任何地方都找不到任何东西。

有人知道为什么这可能突然成为 4.5 版本中的问题吗?如何解决?

XslCompiledTransform transform = new XslCompiledTransform();
transform.Load(XmlReader.Create(report), new XsltSettings { EnableScript = true }, new XmlUrlResolver());

report是一个包含大型 XSLT 样式表的 MemoryStream。

4

3 回答 3

10

原来这是 .Net Framework 4.5 中的一个功能/缺陷。来自微软的消息...

我们最近在修补程序汇总中发布了一个修复程序。请参阅http://support.microsoft.com/kb/2828843了解 .NET Framework 4.0 和http://support.microsoft.com/kb/2828841了解 .NET Framework 4.5。

然后将其添加到您的配置文件中,问题应该会消失。

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
    <sectionGroup name="system.xml">
      <section name="xslt" type="System.Xml.XmlConfiguration.XsltConfigSection, System.Xml, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false"/>
    </sectionGroup>
  </configSections>
  <system.xml>
    <xslt limitXPathComplexity="false"/>
  </system.xml>
  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5"/>
  </startup>
</configuration>

这解决了我的问题。

于 2013-05-02T14:54:33.743 回答
2

我遇到了同样的问题,并将其隔离到一个机器生成的具有超过 1500 个 xsl:when-elements 的选择元素中。进一步的测试证明 .NET 4.7 会在 789 个或更多的 when-elements 处给出“太复杂”的异常。

在 app.config 中将 limitXPathComplexity 设置为 false 会导致程序崩溃并引发 StackOverflowException。

.NET Core 2.0 上的相同代码会在 appx 2800 个元素处引发 StackOverflowException。我已经向两个团队报告了这个错误,但不要指望它很快就会被优先考虑。

于 2018-02-18T11:03:17.407 回答
0

我通过将用于键/值映射的数千个 xsl:choose 和 xsl:if 语句替换为外部 xml 文件键/值查找来解决此问题。

这里抄袭的方法 - 下面的学分。

就 XSLT 而言,最好的方法是将查找数据作为 XML 文档,然后您可以使用 XSLT 文档函数加载该文档。例如,如果您的查找 XML 格式为

<list>
  <data key="k1" value="value 1"/>
  <data key="k2" value="value 2"/>
  <data key="k3" value="value 3"/>
</list>

然后使用 XSLT 你可以做例如

<xsl:variable name="data" select="document('lookup.xml')/list/data"/>

<xsl:for-each select="foo">
  <xsl:value-of select="$data[@key = current()]/@value"/>
</xsl:for-each>

无需 xsl:choose。当然,文档函数不必加载静态文件,它可以向提供 XML 的 HTTP 服务器发出 GET 请求。

学分: https ://social.msdn.microsoft.com/Forums/en-US/9b5966a1-aa1e-46db-88f8-3f4a9aeadb5b/best-way-to-handle-a-lookup-in-xslt-data-is-已经在数据库中?forum=xmlandnetfx

http://etutorials.org/XML/xml+hacks/Chapter+3.+Transforming+XML+Documents/Hack+56+Use+Lookup+Tables+with+XSLT+to+Translate+FIPS+Codes/

于 2018-03-20T10:55:12.443 回答