Исключение при загрузке внешнего XSLT - PullRequest
2 голосов
/ 15 февраля 2011

У меня есть загрузка 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, поэтому не уверен, что вам нужно.

Ответы [ 3 ]

2 голосов
/ 15 февраля 2011

Только общий модуль EXSLT поддерживается .NET XSLT engine .Чтобы использовать весь EXSLT, вы должны использовать один из перечисленных здесь совместимых движков (или переписать ваши таблицы стилей):

EXSLT - func: function

РЕДАКТИРОВАТЬ: Возможно, вам повезет, если вы используете библиотеку Mvp.Xml, разработанную некоторыми Microsoft MVP, которая доступна в Codeplex.Он предлагает некоторую поддержку EXSLT:

Mvp.Xml Project

1 голос
/ 21 февраля 2011

Спасибо за всю помощь.

Я не мог заставить это работать, используя любую из нативных библиотек .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));
        }
    }
}    
1 голос
/ 15 февраля 2011

Вам нужно посмотреть в вашем XSLT-документе пространство имен http://dlxs.org. Я бы зашел на сайт здесь:

http://www.dlxs.org/products/index.html

Похоже, ваш XSLT использует некоторые необходимые расширения.

...