Я преобразую 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 решение этой проблемы?