执行'文件()'功能被禁止."其中EnableDocumentFunction设置为true
本文关键字:EnableDocumentFunction 其中 设置 true quot 功能 文件 执行 禁止 | 更新日期: 2023-09-27 18:15:23
当尝试xslt转换时,我在生产环境中得到一个间歇性的System.Xml.Xsl.XslTransformException异常,不幸的是我无法在开发环境中复制此异常。
异常给出了更多的细节:
然而,EnableDocumentFunction属性在处理代码中被设置为true:禁止执行'document()'函数。使用XsltSettings。EnableDocumentFunction属性来启用它。一个错误发生在C:'path'to'file'CDS.xsl(16,3).
private void Transform()
{
var keepTrying = true;
var tryCount = 0;
const int maxRetrys = 3;
while (keepTrying)
{
try
{
var xmlResolver = new XmlUrlResolver();
using (var xmlFile = new XmlNodeReader(_xDoc))
{
var settings = new XmlReaderSettings
{
XmlResolver = xmlResolver,
ProhibitDtd = false,
DtdProcessing = DtdProcessing.Ignore
};
using (var xsl = XmlReader.Create(_xslPath, settings))
{
var xslt = new XslCompiledTransform(true);
xslt.Load(xsl, new XsltSettings { EnableDocumentFunction = true }, xmlResolver);
var sb = new StringBuilder();
using (var writer = XmlWriter.Create(sb, xslt.OutputSettings))
{
xslt.Transform(xmlFile, null, writer, xmlResolver); // errors out here.
}
var xhtml = sb.ToString();
_transformedXml = xhtml;
_isTransformed = true;
xsl.Close();
}
}
keepTrying = false;
}
catch (System.Xml.Xsl.XsltException ex)
{
ExceptionPolicy.HandleException(ex, "ExceptionLogging");
tryCount++;
if (tryCount > maxRetrys)
{
keepTrying = false;
throw;
}
}
}
}
xslt文件由第三方提供并自动更新,因此不能重写它。下面是它的顶部,出于隐私原因稍作修改:
<?xml version="1.0"?>
<!--
Interaction_550.xsl : 20110916
-->
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:example="http://www.example.com" version="1.0">
<xsl:param name="D2DSeverityFilter"></xsl:param>
<xsl:param name="D2HSeverityFilter"></xsl:param>
<xsl:param name="DocumentationFilter"></xsl:param>
<xsl:output method="html"/>
<xsl:key name="d2d_sev_level-lookup" match="example:d2d_sev_level" use="@name"/>
<xsl:key name="d2h_sev_level-lookup" match="example:d2h_sev_level" use="@name"/>
<xsl:key name="d2l_sev_level-lookup" match="example:d2l_sev_level" use="@name"/>
<xsl:key name="preg_cat-lookup" match="example:preg_cat" use="@cat"/>
<xsl:key name="doc_level-lookup" match="example:doc_level" use="@name"/>
<xsl:variable name="d2d_sev_level-top" select="document('')/*/example:d2d_sev_levels"/>
<xsl:variable name="d2h_sev_level-top" select="document('')/*/example:d2h_sev_levels"/>
<xsl:variable name="d2l_sev_level-top" select="document('')/*/example:d2l_sev_levels"/>
<xsl:variable name="doc_level-top" select="document('')/*/example:doc_levels"/>
<xsl:variable name="preg_cat-top" select="document('')/*/example:preg_cats"/>
<xsl:template match="/">
<head>
<style type="text/css">
body {
font-family : arial,sans serif,helvetica;
}
...
如何:
- 修复这个,使它不发生吗?
- 如果做不到这一点,我该如何在开发中复制它?
或者使用MS XslCompiledTransform类,您可以使用XsltSettings类来避免此错误,因为它由错误本身描述。从MSDN
这是一种摆脱document('')/*/someName
表达式的一般方法:
原始转换用一个特殊的转换处理,该转换生成一个等价的转换,该转换不包含document('')
函数调用。
那么您只需要使用生成的转换。
:
这个转换(让它命名为tA
),包含document('')
:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:my="my:my" >
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<my:paramDoc1>
<x>123</x>
<y>37</y>
</my:paramDoc1>
<my:paramDoc2>
<x>456</x>
<y>79</y>
</my:paramDoc2>
<xsl:variable name="vpDoc1" select="document('')/*/my:paramDoc1"/>
<xsl:variable name="vpDoc2" select="document('')/*/my:paramDoc2"/>
<xsl:template match="/*">
<xsl:value-of select="$vpDoc1/x"/>
<xsl:text>|</xsl:text>
<xsl:value-of select="$vpDoc2/y"/>
</xsl:template>
</xsl:stylesheet>
当应用于任何文档时,产生:
123|79
现在我们用这个(tGen
):
处理上面的转换<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:x="a:a" exclude-result-prefixes="x">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:namespace-alias stylesheet-prefix="x"
result-prefix="xsl"/>
<xsl:variable name="vApos">'</xsl:variable>
<xsl:variable name="vSelectPrefix" select=
"concat('document(', $vApos,$vApos, ')/*/')"/>
<xsl:template match="node()|@*" name="identity">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="xsl:stylesheet">
<x:stylesheet xmlns:ext="http://exslt.org/common">
<xsl:copy-of select="@*"/>
<xsl:apply-templates/>
</x:stylesheet>
</xsl:template>
<xsl:template match="xsl:variable">
<xsl:variable name="vSelattr" select="@select"/>
<xsl:choose>
<xsl:when test="not(starts-with(@select, $vSelectPrefix))">
<xsl:call-template name="identity"/>
</xsl:when>
<xsl:otherwise>
<x:variable name="vrtf{@name}">
<xsl:copy-of select=
"/*/*[name()
= substring-after($vSelattr, $vSelectPrefix)
]"/>
</x:variable>
<x:variable name="{@name}" select=
"ext:node-set($vrtf{@name})/*"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
结果是一个新的转换(tRes
),它不包含像document('')
这样的表达式:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ext="http://exslt.org/common">
<xsl:output omit-xml-declaration="yes"
indent="yes" xmlns:my="my:my" />
<xsl:strip-space elements="*" xmlns:my="my:my" />
<my:paramDoc1 xmlns:my="my:my">
<x>123</x>
<y>37</y>
</my:paramDoc1>
<my:paramDoc2 xmlns:my="my:my">
<x>456</x>
<y>79</y>
</my:paramDoc2>
<xsl:variable name="vrtfvpDoc1">
<my:paramDoc1 xmlns:my="my:my">
<x>123</x>
<y>37</y>
</my:paramDoc1>
</xsl:variable>
<xsl:variable name="vpDoc1" select="ext:node-set($vrtfvpDoc1)/*" />
<xsl:variable name="vrtfvpDoc2">
<my:paramDoc2 xmlns:my="my:my">
<x>456</x>
<y>79</y>
</my:paramDoc2>
</xsl:variable>
<xsl:variable name="vpDoc2" select="ext:node-set($vrtfvpDoc2)/*" />
<xsl:template match="/*" xmlns:my="my:my">
<xsl:value-of select="$vpDoc1/x" />
<xsl:text>|</xsl:text>
<xsl:value-of select="$vpDoc2/y" />
</xsl:template>
</xsl:stylesheet>
如果我们现在将这个动态生成的转换(tRes
)应用于任何XML文档,结果与将原始转换(tA
)应用于此文档时的完全相同:
123|79
因此,我们可以使用tGen
将包含document('')
表达式的转换转换为不包含这些表达式的等价转换。