xsd:在Embedded Resource XSD中导入

Jef*_*sen 4 .net c# xsd visual-studio-2010 embedded-resource

我有一个类库项目,在我的解决方案中包含其他项目之间的一些共享代码.其中一个共享代码涉及对XSD文件运行XML验证.XSD的名称作为参数传递给方法,然后使用Assembly.GetFile().

问题是XSD文件导入了另外两个XSD.我已经将所有三个作为资源加载到我的类库中但是从我读过的xsd:import不起作用.是否有其他方法可以在我的类库项目中使用这些XSD而不会破坏这些xsd:import语句?

编辑 - 更新

我在下面实施了亚历山大的建议,但正如我在评论中所述,无论什么时候GetEntity()需要xs:import'd XSD,ofObjectToReturn都是null.这导致第一个xs:import"d类型抛出异常"类型的实例未定义."

为了解决这个问题,我改变GetEntity()了回归,GetManifestResourceStream()无论其ofObjectToReturn价值如何.现在这似乎适用于第一级xs:import语句,但xs:import其中一个原始xs:importXSD中的辅助语句不起作用.我已经确认GetEntity()正在调用此辅助节点,xs:import但我收到了此辅助XSD中定义的类型的"未定义类型"异常.

  • TopLevel.xsd - 类型解析正常
    • FirstLevelImport1.xsd - 类型解析正常
    • FirstLevelImport2.xsd - 类型解析正常
      • SecondLevelImport1.xsd - 为此XSD中定义的类型抛出"type not defined"异常

XmlReader.Create()传递XmlReaderSettings定义模式验证期间抛出"未定义类型"异常.

Ale*_*tov 5

要解决这些文件,这是由两种添加xsd:import或者xsd:include您可以使用自定义的XmlResolver.您可以在下面找到ResourceXmlResolver的示例.它假设程序集的名称是" AYez.EmbeddedXsdTests ".

using System.Xml;
using System.Xml.Schema;
using NUnit.Framework;

namespace AYez.EmbeddedXsdTests
{
    [TestFixture]
    public class EmbeddedXsdTests
    {
        [Test]
        public void SomeEntryPoint()
        {
            var schemaSet = new XmlSchemaSet {XmlResolver = new ResourceXmlResolver()};
            schemaSet.Add("rrn:org.xcbl:schemas/xcbl/v4_0/financial/v1_0/financial.xsd", @"Invoice.xsd");
            schemaSet.Compile();

            var settings = new XmlReaderSettings { ValidationType = ValidationType.Schema, Schemas = schemaSet };

            settings.ValidationEventHandler += delegate(object o, ValidationEventArgs e)
            {
                switch (e.Severity)
                {
                    case XmlSeverityType.Error:
                        Console.Write("Error: {0}", e.Message);
                        break;
                    case XmlSeverityType.Warning:
                        Console.Write("Warning: {0}", e.Message);
                        break;
                }
            };
            var xmlReader = XmlReader.Create(@"d:\temp\Invoice.xml", settings);
            while (xmlReader.Read()) { /*TODO: Nothing*/} // Validation is performed while reading

        }
    }

    public class ResourceXmlResolver: XmlResolver
    {
        /// <summary>
        /// When overridden in a derived class, maps a URI to an object containing the actual resource.
        /// </summary>
        /// <returns>
        /// A System.IO.Stream object or null if a type other than stream is specified.
        /// </returns>
        /// <param name="absoluteUri">The URI returned from <see cref="M:System.Xml.XmlResolver.ResolveUri(System.Uri,System.String)"/>. </param><param name="role">The current version does not use this parameter when resolving URIs. This is provided for future extensibility purposes. For example, this can be mapped to the xlink:role and used as an implementation specific argument in other scenarios. </param><param name="ofObjectToReturn">The type of object to return. The current version only returns System.IO.Stream objects. </param><exception cref="T:System.Xml.XmlException"><paramref name="ofObjectToReturn"/> is not a Stream type. </exception><exception cref="T:System.UriFormatException">The specified URI is not an absolute URI. </exception><exception cref="T:System.ArgumentNullException"><paramref name="absoluteUri"/> is null. </exception><exception cref="T:System.Exception">There is a runtime error (for example, an interrupted server connection). </exception>
        public override object GetEntity(Uri absoluteUri, string role, Type ofObjectToReturn)
        {   
                // If ofObjectToReturn is null, then any of the following types can be returned for correct processing:
                // Stream, TextReader, XmlReader or descendants of XmlSchema
                var result =  this.GetType().Assembly.GetManifestResourceStream(string.Format("AYez.EmbeddedXsdTests.{0}",
                                                                                             Path.GetFileName(absoluteUri.ToString())));                
                // set a conditional breakpoint "result==null" here
                return result;
        }

        /// <summary>
        /// When overridden in a derived class, sets the credentials used to authenticate Web requests.
        /// </summary>
        /// <returns>
        /// An <see cref="T:System.Net.ICredentials"/> object. If this property is not set, the value defaults to null; that is, the XmlResolver has no user credentials.
        /// </returns>
        public override ICredentials Credentials
        {
            set { throw new NotImplementedException(); }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)