加载外部 XSLT 时发生异常

发布于 2024-10-17 09:14:41 字数 2662 浏览 8 评论 0原文

我有大量来自第三方的 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

初与友歌 2024-10-24 09:14:41

.NET XSLT 引擎仅支持 EXSLT 通用模块。要使用全部 EXSLT,您必须使用此处列出的兼容引擎之一(或重写样式表):

EXSLT - func:function

编辑:您使用由某些 Microsoft MVP 开发的 Mvp.Xml 库可能会很幸运,该库可在 Codeplex 上找到。它提供了一些 EXSLT 支持:

Mvp.Xml 项目

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):

EXSLT - func:function

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:

Mvp.Xml Project

舟遥客 2024-10-24 09:14:41

您需要查看 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.

复古式 2024-10-24 09:14:41

感谢您的所有帮助。

我无法使用任何本机 .NET 库来实现此功能,因此解决了这个问题。使用它的程序仅打算运行一次来​​填充数据库,因此性能并不是非常重要。对于那些对此感兴趣的人来说,这是我的解决方案。我使用 XSLTProc.exe 转换数据,以临时文件的形式流式传输到磁盘,然后再次读回输出。令人讨厌但有效。

using (TemporaryFile oTempInputFile = new TemporaryFile())
{
    //write the content out to the temporary file
    using (StreamWriter oWriter = new StreamWriter(oTempInputFile.FilePath, false, System.Text.Encoding.UTF8))
    {
        oWriter.WriteLine("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
        oWriter.WriteLine(oTextNode.OuterXml);
        oWriter.Close();
    }


    using (TemporaryFile oTempOutputFile = new TemporaryFile())
    {
        try
        {
            String sXSLTProcArguments = "-o \"" + oTempOutputFile.FilePath + "\" \"" + oJob.ContentTemplate + "\" \"" + oTempInputFile.FilePath + "\"";

            Process oProcess = new Process();
            oProcess.StartInfo.UseShellExecute = false;
            oProcess.StartInfo.FileName = oJob.XSLTParser;
            oProcess.StartInfo.Arguments = sXSLTProcArguments;
            oProcess.StartInfo.RedirectStandardOutput = true;
            oProcess.StartInfo.RedirectStandardError = true;
            oProcess.StartInfo.CreateNoWindow = true;
            oProcess.StartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
            oProcess.Start();
            oProcess.WaitForExit(5000);

            if (File.Exists(oTempOutputFile.FilePath))
            {
                using (StreamReader oReader = new StreamReader(oTempOutputFile.FilePath))
                {
                    String sHTML = oReader.ReadToEnd();

                    if (sHTML.Length == 0)
                    {
                        Logger.Write(new DebugLogEntry("No HTML content was generated"));
                    }
                    else
                    {
                        //Do something with sHTML
                    }
                }
            }
            else
            {
                Logger.Write(new GeneralLogEntry("Failed to transform content for " + sDocumentID));
            }
        }
        catch (Exception e)
        {
            Logger.Write(new GeneralLogEntry("Exception thrown when transforming content for " + sDocumentID));
            Logger.Write(new DebugLogEntry(e.Message));
            Logger.Write(new DebugLogEntry(e.StackTrace));
        }
    }
}    

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.

using (TemporaryFile oTempInputFile = new TemporaryFile())
{
    //write the content out to the temporary file
    using (StreamWriter oWriter = new StreamWriter(oTempInputFile.FilePath, false, System.Text.Encoding.UTF8))
    {
        oWriter.WriteLine("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
        oWriter.WriteLine(oTextNode.OuterXml);
        oWriter.Close();
    }


    using (TemporaryFile oTempOutputFile = new TemporaryFile())
    {
        try
        {
            String sXSLTProcArguments = "-o \"" + oTempOutputFile.FilePath + "\" \"" + oJob.ContentTemplate + "\" \"" + oTempInputFile.FilePath + "\"";

            Process oProcess = new Process();
            oProcess.StartInfo.UseShellExecute = false;
            oProcess.StartInfo.FileName = oJob.XSLTParser;
            oProcess.StartInfo.Arguments = sXSLTProcArguments;
            oProcess.StartInfo.RedirectStandardOutput = true;
            oProcess.StartInfo.RedirectStandardError = true;
            oProcess.StartInfo.CreateNoWindow = true;
            oProcess.StartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
            oProcess.Start();
            oProcess.WaitForExit(5000);

            if (File.Exists(oTempOutputFile.FilePath))
            {
                using (StreamReader oReader = new StreamReader(oTempOutputFile.FilePath))
                {
                    String sHTML = oReader.ReadToEnd();

                    if (sHTML.Length == 0)
                    {
                        Logger.Write(new DebugLogEntry("No HTML content was generated"));
                    }
                    else
                    {
                        //Do something with sHTML
                    }
                }
            }
            else
            {
                Logger.Write(new GeneralLogEntry("Failed to transform content for " + sDocumentID));
            }
        }
        catch (Exception e)
        {
            Logger.Write(new GeneralLogEntry("Exception thrown when transforming content for " + sDocumentID));
            Logger.Write(new DebugLogEntry(e.Message));
            Logger.Write(new DebugLogEntry(e.StackTrace));
        }
    }
}    
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文