C# 中的 XSLT 转换 - 如何获取包含文档的有效 URL?

Posted

技术标签:

【中文标题】C# 中的 XSLT 转换 - 如何获取包含文档的有效 URL?【英文标题】:XSLT transform in C# - how to get valid URLs for included documents? 【发布时间】:2020-06-05 15:34:51 【问题描述】:

我正在使用 XSLT 表转换 XML。该工作表由几个文件组成,包括如下:

<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 传递给解析器?或者可能是其他更通用的解决方案?

【问题讨论】:

【参考方案1】:

如果你有一个带有主样式表模块的文件名或 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).

【讨论】:

以上是关于C# 中的 XSLT 转换 - 如何获取包含文档的有效 URL?的主要内容,如果未能解决你的问题,请参考以下文章

如何对适配器中的输入请求执行 xslt 转换

XSLT

为啥 XSLT 文档被认为是“样式表”?

如何使用 C# ASP.Net 从 XML 文档中获取特定 XML 元素的列表?

[XML]学习笔记XSLT

如何在 C# 中应用 XSLT 样式表