使用c#中的程序集导入Xslt

本文关键字:导入 Xslt 程序集 使用 | 更新日期: 2023-09-27 18:08:46

我有一个xslt文件myxslt。Xslt,它包含一个导入,看起来像这样:

<?xml version="1.0" encoding="utf-8"?>    
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:import href="someOtherXsltFile.xslt"/>
  <!--Do some transformations -->  
</xsl:stylesheet>

我试图通过使用程序集将这些文件导入到我的c#应用程序中:

Assembly assembly = Assembly.GetExecutingAssembly();
        using (Stream xsltStream = assembly.GetManifestResourceStream(mynamespace.myxslt.xslt))
        {
            using (XmlReader xsltReader = XmlReader.Create(xsltStream))
            {
                xslt.Load(xsltReader);
            }
        }

正如我在这个答案中看到的:添加(嵌入式资源)模式到XmlReaderSettings而不是文件名?

Stream和XmlReader加载良好。

然而,当我尝试加载xslt时,我的应用程序抛出无法找到文件异常。无法加载的文件为someOtherXsltFile.xslt

这两个文件都作为嵌入式资源加载,并且都在assembly.GetManifestResourceNames的列表中可见。

我宁愿不改变xslt文件中的任何内容,因为这些是我试图转换的消息附带的标准文件。

是否有一种方法来加载我的xslt使用从程序集导入?

使用c#中的程序集导入Xslt

感谢stuartd发布的链接(如何在从字符串加载XSL的转换中解析XSL包含?)我已经设法找出解决办法了。

我的导入现在看起来像这样:

        Assembly assembly = Assembly.GetExecutingAssembly();
        using (Stream xsltStream = assembly.GetManifestResourceStream(mynamespace.myxslt.xslt))
        {
            using (XmlReader xsltReader = XmlReader.Create(xsltStream))
            {
                var resolver = new MyXmlUrlResolver();
                xslt.Load(xsltReader,null,resolver);
            }
        }

MyXmlUrlResolver定义如下:

private class MyXmlUrlResolver : XmlUrlResolver
    {
        private const string basePad = "MyNamespace.mysubnamespace.";
        public override object GetEntity(Uri absoluteUri, string role, Type ofObjectToReturn)
        {
            switch (absoluteUri.Scheme)
            {
                case "file":
                    {
                        string origString = absoluteUri.OriginalString;
                        Assembly assembly = Assembly.GetExecutingAssembly();
                        // the filename starts after the last '
                        int index = origString.LastIndexOf('''');                            
                        string filename = origString.Substring(index + 1);
                        string resourceName = basePad + filename;
                        var stream = assembly.GetManifestResourceStream(resourceName);
                        return stream;
                    }
                default:
                    {
                        return (Stream)base.GetEntity(absoluteUri, role, ofObjectToReturn);
                    }
            }
        }
    }

这将加载包含所有导入的xslt。