加载外部 XSLT 时发生异常
我有大量来自第三方的 XSLT,我需要用它来转换一些数据。
如果我使用 xsltproc 它工作正常并按预期输出数据。
我有以下 C# 代码来尝试在进程中使用它:
sXML is the chunk of XML oJob.ContentTemplate 是 XSLT 文件的本地文件路径
try
{
using (StringWriter oOutputString = new StringWriter())
{
using (XmlTextWriter oOutputWriter = new XmlTextWriter(oOutputString))
{
using (StringReader oInputString = new StringReader(sXML))
{
using (XmlTextReader oInputReader = new XmlTextReader(oInputString))
{
XslCompiledTransform oXSLTTransform = new XslCompiledTransform();
oXSLTTransform.Load(oJob.ContentTemplate, XsltSettings.TrustedXslt, new XmlUrlResolver());
oXSLTTransform.Transform(oInputReader, oOutputWriter);
String sHTML = oOutputWriter.ToString();
}
}
}
}
}
catch (Exception e)
{}
抛出的异常是:
附加信息:找不到实现前缀“http://dlxs.org”的脚本或外部对象。
XSLT 相当复杂,我目前不理解其中的大部分内容。有没有一种方法可以让我在不深入研究 XSLT 的情况下完成这项工作?
Visual Studio 2010 应该支持 EXSLT 对吧?
编辑:如果我启用调试并进入其中,我可以看到该行的错误:
<xsl:import href="../../lib/xslfunctions.xsl"/>
......
<xsl:when test="contains($BibRegions, dlxs:normAttr($searchRgn))">
这些函数应该已经包含在内,本地 XSLT 文件之一包含此内容:
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:str="http://exslt.org/strings" xmlns:exsl="http://exslt.org/common" xmlns:func="http://exslt.org/functions" xmlns:dlxs="http://dlxs.org" extension-element-prefixes="str exsl dlxs func" exclude-result-prefixes="str exsl dlxs func">
<!-- extension functions -->
<func:function name="dlxs:normAttr">
<xsl:param name="attr"/>
<!-- strip out spaces,commas,question marks -->
<xsl:variable name="temp" select="translate($attr,' ,?','')"/>
<func:result select="translate($temp,'ABCDEFGHIJKLMNOPQRSTUVWXYZ','abcdefghijklmnopqrstuvwxyz')"/>
</func:function>
.....
</xsl:stylesheet>
Visual Studio 是否无法打开这些文件,因为它们使用 UNIX路径还是因为安全问题而无法打开本地文件?
编辑 2:
我使用的扩展是:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:str="http://exslt.org/strings"
xmlns:exsl="http://exslt.org/common"
xmlns:func="http://exslt.org/functions"
xmlns:dlxs="http://dlxs.org"
extension-element-prefixes="str exsl dlxs func"
exclude-result-prefixes="str exsl dlxs func">
我是 XSLT 初学者,所以不确定您需要什么。
I have a load of XSLT from a third party which i need to use to transform some data.
If I use xsltproc it works fine and outputs data as expected.
I have the following C# code to try and use it in-process:
sXML is the lump of XML
oJob.ContentTemplate is the local file path to the XSLT file
try
{
using (StringWriter oOutputString = new StringWriter())
{
using (XmlTextWriter oOutputWriter = new XmlTextWriter(oOutputString))
{
using (StringReader oInputString = new StringReader(sXML))
{
using (XmlTextReader oInputReader = new XmlTextReader(oInputString))
{
XslCompiledTransform oXSLTTransform = new XslCompiledTransform();
oXSLTTransform.Load(oJob.ContentTemplate, XsltSettings.TrustedXslt, new XmlUrlResolver());
oXSLTTransform.Transform(oInputReader, oOutputWriter);
String sHTML = oOutputWriter.ToString();
}
}
}
}
}
catch (Exception e)
{}
The exception thrown is:
Additional information: Cannot find the script or external object that implements prefix 'http://dlxs.org'.
The XSLT is fairly complicated and I don't understand most of it currently. Is there a way I can get this working without delving too far into the XSLT?
Visual Studio 2010 should support EXSLT right?
Edit : If i enable debug and step into it I can see the error on the line:
<xsl:import href="../../lib/xslfunctions.xsl"/>
......
<xsl:when test="contains($BibRegions, dlxs:normAttr($searchRgn))">
These functions should be included already, one of the local XSLT files contains this:
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:str="http://exslt.org/strings" xmlns:exsl="http://exslt.org/common" xmlns:func="http://exslt.org/functions" xmlns:dlxs="http://dlxs.org" extension-element-prefixes="str exsl dlxs func" exclude-result-prefixes="str exsl dlxs func">
<!-- extension functions -->
<func:function name="dlxs:normAttr">
<xsl:param name="attr"/>
<!-- strip out spaces,commas,question marks -->
<xsl:variable name="temp" select="translate($attr,' ,?','')"/>
<func:result select="translate($temp,'ABCDEFGHIJKLMNOPQRSTUVWXYZ','abcdefghijklmnopqrstuvwxyz')"/>
</func:function>
.....
</xsl:stylesheet>
Is it that Visual Studio can't open these files because they use UNIX paths or because it can't open the local files due to security issues?
Edit 2 :
The extensions that I'm using are:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:str="http://exslt.org/strings"
xmlns:exsl="http://exslt.org/common"
xmlns:func="http://exslt.org/functions"
xmlns:dlxs="http://dlxs.org"
extension-element-prefixes="str exsl dlxs func"
exclude-result-prefixes="str exsl dlxs func">
I'm very much an XSLT beginner so aren't sure what you need.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
.NET XSLT 引擎仅支持 EXSLT 通用模块。要使用全部 EXSLT,您必须使用此处列出的兼容引擎之一(或重写样式表):
编辑:您使用由某些 Microsoft MVP 开发的 Mvp.Xml 库可能会很幸运,该库可在 Codeplex 上找到。它提供了一些 EXSLT 支持:
Only the EXSLT Common module is supported by the .NET XSLT engine. To use all of EXSLT, you must use one of the compatible engines listed here (or rewrite your stylesheets):
EDIT: You might get lucky using the Mvp.Xml library developed by some Microsoft MVPs which is available at Codeplex. It offers some EXSLT support:
您需要查看 XSLT 文档中的命名空间 http://dlxs.org。我会访问这里的网站:
http://www.dlxs.org/products/index。 html
看起来您的 XSLT 正在使用一些所需的扩展。
You need to look at your XSLT document for the namespace http://dlxs.org. I would go out to the website here:
http://www.dlxs.org/products/index.html
Looks like your XSLT is using some extensions that are needed.
感谢您的所有帮助。
我无法使用任何本机 .NET 库来实现此功能,因此解决了这个问题。使用它的程序仅打算运行一次来填充数据库,因此性能并不是非常重要。对于那些对此感兴趣的人来说,这是我的解决方案。我使用 XSLTProc.exe 转换数据,以临时文件的形式流式传输到磁盘,然后再次读回输出。令人讨厌但有效。
Thanks for all of the help.
I couldn't get this working using any of the native .NET libraries so worked around it. The program that this is used in is only ever intended to be run once to populate a database so performance isn't incredibly important. For those of you who are interested here is my solution. I use XSLTProc.exe to transform the data, streaming out to disk in a temporary file and then read the output back in again. Nasty but works.