简体   繁体   English

在 C# 中使用从程序集导入加载 Xslt

[英]Load Xslt with import from assembly in C#

I have a xslt file, myxslt.xslt, that contains an import, that looks a bit like this:我有一个 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>

I am trying to import these files into my C# application by using the assembly:我正在尝试使用程序集将这些文件导入到我的 C# 应用程序中:

Assembly assembly = Assembly.GetExecutingAssembly();

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

as I saw in this answer: Adding (Embedded Resource) Schema To XmlReaderSettings Instead Of Filename?正如我在这个答案中看到的: 将(嵌入式资源)架构添加到 XmlReaderSettings 而不是文件名?

The Stream and XmlReader load fine. Stream 和 XmlReader 加载正常。

However my application throws a cannot find file exception when I try to load the xslt.但是,当我尝试加载 xslt 时,我的应用程序抛出了找不到文件异常。 The file that it cannot load is someOtherXsltFile.xslt .它无法加载的文件是someOtherXsltFile.xslt

Both files are loaded as an embedded resource and both are visible in the list from assembly.GetManifestResourceNames .这两个文件都作为嵌入式资源加载,并且都在assembly.GetManifestResourceNames的列表中可见。

I would rather not change anything in the xslt files as those are standard files that came with the messages that I am trying to transform.我宁愿不更改 xslt 文件中的任何内容,因为这些是我尝试转换的消息随附的标准文件。

Is there a way to load my xslt using an import from the assembly?有没有办法使用从程序集中导入来加载我的 xslt?

Thanks to the link posted by stuartd ( How to resolve XSL includes in a Transformation that loads XSL from a String? ) I have managed to figure out the solution.感谢 stuartd 发布的链接( 如何解析 XSL 包含在从字符串加载 XSL 的转换中? )我设法找出了解决方案。

My import now looks like this:我的导入现在看起来像这样:

        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);
            }
        }

And the MyXmlUrlResolver is defined as follows: 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);
                    }
            }
        }
    }

This loads the xslt including all of its imports.这将加载 xslt,包括其所有导入。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM