XSLT-преобразование в C# - как получить действительные URL-адреса для включенных документов? - PullRequest
0 голосов
/ 21 февраля 2020

Я преобразую XML, используя лист XSLT. Лист состоит из нескольких файлов, которые включаются следующим образом:

<xsl:include href="tokens.xsl"/>
<xsl:include href="glayout.xsl"/>
<xsl:include href="scripts.xsl"/>
<xsl:include href="tables.xsl"/>
<xsl:include href="entities.xsl"/>
<xsl:include href="cmarkup.xsl"/>

Код преобразования выглядит следующим образом:

// Load text
var reader = XmlReader.Create(new StringReader(text));

// Load transform
XslCompiledTransform myXslTrans = new XslCompiledTransform();
using (var fs = new FileStream(result.FileName, FileMode.Open, FileAccess.Read))
{
    var xmlReader = XmlReader.Create(fs);
    myXslTrans.Load(xmlReader);
}

// Perform transformation
MemoryStream ms = new MemoryStream();
XmlTextWriter writer = new XmlTextWriter(ms, Encoding.UTF8);
myXslTrans.Transform(reader, null, writer);

// Recover result to string
ms.Seek(0, SeekOrigin.Begin);
var textReader = new StreamReader(ms);
string transformed = textReader.ReadToEnd();

Преобразование завершается неудачно в строках включения. Я обнаружил, что могу предоставить свой собственный распознаватель для предоставления отсутствующих документов, но, поскольку их URL-адреса являются относительными, я добавляю их в папку текущего приложения, например:

D:\Dokumenty\Dev\VS\Dev.Editor\Dev.Editor\bin\Debug\tokens.xsl

Существует два грязных решения. :

  • Отрежьте путь к приложению, чтобы получить только имя файла, затем найдите файл в папке исходного листа (но что, если файл имеет подпапку, например: Include/tokens.xsl?
  • Временно установите текущий каталог на тот, в котором находится основной лист:
    var dir = System.IO.Directory.GetCurrentDirectory();
    try
    {
        System.IO.Directory.SetCurrentDirectory(System.IO.Path.GetDirectoryName(result.FileName));
        myXslTrans.Load(xmlReader, null, resolver);
    }
    finally
    {
        System.IO.Directory.SetCurrentDirectory(dir);
    }

Но мне тоже не нравится это решение. Есть ли способ заставить XslCompiledTransform передать оригинал URL-адреса для распознавателя? Или, возможно, другое, более общее c решение этой проблемы?

1 Ответ

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

Если у вас есть имя файла или URI с основным модулем таблицы стилей, используйте перегрузку метода Load, принимая строку (https://docs.microsoft.com/en-us/dotnet/api/system.xml.xsl.xslcompiledtransform.load?view=netframework-4.8#System_Xml_Xsl_XslCompiledTransform_Load_System_String_), например, myXslTrans.Load(result.FileName).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...