我从第三方获得了大量的XSLT,我需要用它来转换一些数据。
如果我使用xsltproc,它可以正常工作并按预期输出数据。
我有以下C#代码尝试在进程中使用它:
sXML是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初学者,所以不确定你需要什么。
答案 0 :(得分:2)
仅限EXSLT公共模块is supported by the .NET XSLT engine。要使用所有EXSLT,您必须使用此处列出的兼容引擎之一(或重写样式表):
编辑:您可能会幸运地使用由Codeplex提供的一些Microsoft MVP开发的Mvp.Xml库。它提供了一些EXSLT支持:<强> EXSLT - func:function 强>
<强> Mvp.Xml Project 强>
答案 1 :(得分:1)
您需要查看名称空间为http://dlxs.org的XSLT文档。我会去这里的网站:
http://www.dlxs.org/products/index.html
看起来您的XSLT正在使用一些所需的扩展程序。
答案 2 :(得分:1)
感谢所有帮助。
我无法使用任何本机.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));
}
}
}