c# – “禁止执行’document()’函数.”其中EnableDocumentFunct
在尝试xslt转换时,我在生产环境中得到间歇性的System.Xml.Xsl.XslTransformException异常,遗憾的是我无法在开发环境中复制它.
该例外情况进一步详述:
但是,处理代码中的EnableDocumentFunction属性设置为true: 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; } ... 我怎么能够: >解决这个问题,以便它根本不会发生? 解决方法
这是摆脱文档(”)/ * / someName表达式的一般方法:
原始转换使用特殊转换进行处理,该转换生成不包含文档(”)函数调用的等效转换. 然后你只需要使用生成的转换. 例: 这个转换(让我们命名为tA),包含文档(”): <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,')/*/')"/> <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将包含文档(”)表达式的转换转换为不包含此类表达式的等效转换. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |