从 Saxon 9.4he 中的嵌入资源加载 xml 和 xslt [英] Load xml and xslt from embedded resource in Saxon 9.4he

查看:24
本文介绍了从 Saxon 9.4he 中的嵌入资源加载 xml 和 xslt的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用 Saxon 9.4 家庭版 (Saxon-HE 9.4 .NET) 来获取支持 XSLT 2.0 和 XPath 2.0,以及 .NET 中的 XQuery 1.0.当我加载没有 URI 的文件时,我的代码崩溃了.

I am using Saxon 9.4 home edition (Saxon-HE 9.4 .NET) to get support for XSLT 2.0 and XPath 2.0, and XQuery 1.0 in .NET. My code crashes when I load files without an URI.

  1. 是否可以在没有与加载的文档相关的 URI 的情况下加载 xml/xsl 文档?
  2. 如果没有,有没有办法为嵌入在 dll 文件中的元素定义 URI?

任何其他解决方案也将受到赞赏,我唯一的术语是必须从 dll 文件中加载文件.

Any other solutions will also be appreciated, my only term is that the files must be loaded from within the dll-file.

只要我从文件加载 xml/xsl,我的代码就能完美运行:

My code works perfectly as long as i load xml/xsl from file:

const string sourcePath = @"C:	estTestInvoiceWithError.xml";
const string xsltpath = @"C:	estUBL-T10-BiiRules.xsl";

当我尝试从嵌入式资源加载时,代码抛出一个异常,说明'No base URI provided':

When i try to load from embedded resource the code throws an exception stating 'No base URI supplied':

Stream sourceStream = GetEmbeddedResource("TestProject1.testfiles.TestInvoice.xml");
Stream xsltStream = GetEmbeddedResource("TestProject1.testfiles.UBL-T10-BiiRules.xsl");

我还为具有相对路径的资源创建了 Uri,这会引发异常'相对 URI 不支持此操作.':

I have also created Uri's for resources with relative path which throws the exception 'This operation is not supported for a relative URI.':

Uri sourceUri = new Uri("/TestProject1;component/testfiles/TestInvoice.xml",     UriKind.Relative);
Uri xsltUri = new Uri("/TestProject1;component/testfiles/UBL-T10-BiiRules.xsl.xml", UriKind.Relative);

这是我的代码:

using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Text;
using System.Xml;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Saxon.Api;


namespace TestProject1
{
    [TestClass]
    public class XsltTest
    {
        [TestMethod]
        public void SaxonTest()
        {
            Stream sourceStream = GetEmbeddedResource("TestProject1.testfiles.TestInvoice.xml");
            Stream xsltStream = GetEmbeddedResource("TestProject1.testfiles.UBL-T10-BiiRules.xsl");

            Uri sourceUri = new Uri("/TestProject1;component/testfiles/TestInvoice.xml", UriKind.Relative);
            Uri xsltUri = new Uri("/TestProject1;component/testfiles/UBL-T10-BiiRules.xsl.xml", UriKind.Relative);

            const string sourcePath = @"C:	estTestInvoiceWithError.xml";
            const string xsltpath = @"C:	estUBL-T10-BiiRules.xsl";

            Processor processor = new Processor();
            XdmNode input = processor.NewDocumentBuilder().Build(new Uri(sourcePath));

            XsltTransformer transformer = processor.NewXsltCompiler().Compile(new Uri(xsltpath)).Load();

            transformer.InitialContextNode = input;

            Serializer serializer = new Serializer();
            StringBuilder sb = new StringBuilder();
            TextWriter writer = new StringWriter(sb);
            serializer.SetOutputWriter(writer);

            transformer.Run(serializer);

            XmlDocument xmlDocOut = new XmlDocument();
            xmlDocOut.LoadXml(sb.ToString());
            XmlNodeList failedAsserts = xmlDocOut.SelectNodes("/svrl:schematron-output/svrl:failed-assert",XmlInvoiceNamespaceManager());

            if (failedAsserts == null)
                return;

            foreach (XmlNode failedAssert in failedAsserts)
            {
                if (failedAssert.Attributes == null)
                    continue;

                XmlAttribute typeOfError = failedAssert.Attributes["flag"];

                if (typeOfError.Value.Equals("warning"))
                {/*Log something*/}
                else if (typeOfError.Value.Equals("fatal"))
                {/*Log something*/}
            }
        }

        private XmlNamespaceManager XmlInvoiceNamespaceManager()
        {
            IDictionary<string, string> list = new Dictionary<string, string>
                                                   {
                                                       {"xml", "http://www.w3.org/XML/1998/namespace"},
                                                       {"xsi", "http://www.w3.org/2001/XMLSchema-instance"},
                                                       {"xsd", "http://www.w3.org/2001/XMLSchema"},
                                                       {"udt","urn:un:unece:uncefact:data:specification:UnqualifiedDataTypesSchemaModule:2"},
                                                       {"qdt","urn:oasis:names:specification:ubl:schema:xsd:QualifiedDatatypes-2"},
                                                       {"ext","urn:oasis:names:specification:ubl:schema:xsd:CommonExtensionComponents-2"},
                                                       {"ccts", "urn:un:unece:uncefact:documentation:2"},
                                                       {"cbc","urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2"},
                                                       {"cac","urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2"},
                                                       {"inv", "urn:oasis:names:specification:ubl:schema:xsd:Invoice-2"},
                                                       {"svrl", "http://purl.oclc.org/dsdl/svrl"}
                                                   };

            XmlNameTable xmlNameTable = new NameTable();

            XmlNamespaceManager xmlInvoiceNamespaceManager = new XmlNamespaceManager(xmlNameTable);

            foreach (KeyValuePair<string, string> ns in list)
            {
                xmlInvoiceNamespaceManager.AddNamespace(ns.Key, ns.Value);
            }
            return xmlInvoiceNamespaceManager;
        }

        protected static Stream GetEmbeddedResource(string path)
        {
            Assembly asm = Assembly.GetExecutingAssembly();
            Stream stream = asm.GetManifestResourceStream(path);
            return stream;
        }
    }
}

推荐答案

我认为您可以使用 Saxon 从流中加载,但您需要先设置一个基 URI 以允许加载任何引用资源(如 DTD 中的XML 文档或类似的包含或导入的样式表模块).如果您确定您没有那个,那么只需尝试例如

I think you can load from a stream with Saxon but you need to set a base URI first that would allow to load any references resources (like a DTD in an XML document or like included or imported stylesheet modules). If you are sure you don't have that then simply try e.g.

DocumentBuilder db = processor.NewDocumentBuilder();
db.BaseUri = new Uri("file:///C:/");

XdmNode input = db.Build(xsltStream);

显然,如果您需要解析 XSLT 中的相对 URI,这些 URI 也将作为嵌入式资源加载,则需要做更多的工作:您需要将 XmlResolver 设置为支持加载资源的类来自嵌入式资源,连同 XSLT 中的 URI 方案,以向解析器指示您需要从资源加载.我认为 .NET 框架不提供这种 XmlResolver 并且 Uri 类也不支持自定义架构.

Obviously if you need to resolve relative URIs in the XSLT that are also to be loaded as embedded resource more work is needed: you need to set up the XmlResolver to a class that supports loading the resource from an embedded resource, together with a scheme of URIs in the XSLT to indicate to the resolver that you need to load from a resource. I don't think the .NET framework provides such a kind of XmlResolver and the Uri class does not support a custom schema for that either.

这篇关于从 Saxon 9.4he 中的嵌入资源加载 xml 和 xslt的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆