编译两个嵌入式 XSD:错误“无法解析 'schemaLocation' 属性

Compiling two embedded XSDs: error "Cannot resolve 'schemaLocation' attribute

我正在尝试将 2 个嵌入式 XSD 编译成一个 XSD 文件,但出现错误 "cannot resolve 'schemaLocation' attribute"。我不确定如何解决这个问题,但我在猜测它的命名空间。

Schema1.xsd 从 xsd:include 到 Schema2.xsd

Schem1.xsd(嵌入式资源)(简体)

<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns="http://www.somedomain.co.uk/application" xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.somedomain.co.uk/application" elementFormDefault="qualified" attributeFormDefault="unqualified">
  <xsd:include schemaLocation="Schema2.xsd"/>       
</xsd:schema>

Schema2.xsd(嵌入式资源)(简体)

<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://www.somedomain.co.uk/application" targetNamespace="http://www.somedomain.co.uk/application" elementFormDefault="qualified" attributeFormDefault="unqualified" id="someId">
</xsd:schema>

代码

using System;
using System.Reflection;
using System.Xml;
using System.Xml.Schema;

namespace Example
{
    class Program
    {
        public static void Main()
        {
            XmlSchema schema1 = null;

            using (XmlTextReader xtr = new XmlTextReader(Assembly.GetExecutingAssembly().GetManifestResourceStream("Example.Schema1.xsd")))
            {
                schema1 = XmlSchema.Read(xtr, new ValidationEventHandler(XSDValidationEventHandler));
                xtr.Close();
            }

            XmlSchema schema2 = null;

            using (XmlTextReader xtr = new XmlTextReader(Assembly.GetExecutingAssembly().GetManifestResourceStream("Example.Schema2.xsd")))
            {
                schema2 = XmlSchema.Read(xtr, new ValidationEventHandler(XSDValidationEventHandler));
                xtr.Close();
            }

            XmlSchemaSet schemaSet = new XmlSchemaSet();

            schemaSet.ValidationEventHandler += new ValidationEventHandler(XSDValidationEventHandler);
            schemaSet.Add(schema1); //error writes out to console here
            schemaSet.Add(schema2);

            schemaSet.Compile();

            XmlSchema compiledSchema = null;            

            foreach (XmlSchema schema in schemaSet.Schemas())
            {
                compiledSchema = schema;
            }

            Console.WriteLine("Finished");
            Console.ReadKey();
        }

        public static void XSDValidationEventHandler(object sender, ValidationEventArgs args)
        {
            Console.WriteLine(args.Message);
        }  
    }
}

注意:我不能更改 XSD 的内容或将它们更改为非嵌入式资源。

有任何问题随时提问

谢谢

凯尔

当您使用嵌入文件时,默认的 XmlTextReader 无法找到引用的文件。创建 XmlTextReader 后,您必须为其提供一个能够处理嵌入文件的 XmlResolver。

using (XmlTextReader xtr = new XmlTextReader(Assembly.GetExecutingAssembly().GetManifestResourceStream("Example.Schema1.xsd")))
{
  xtr.XmlResolver = new EmbeddedResourceResolver();              
  schema1 = XmlSchema.Read(xtr, new ValidationEventHandler(XSDValidationEventHandler));
            xtr.Close();
}

'EmbeddedResourceResolver'不是现有的框架class,但可以自己创建。您可以在下面找到参考实现。

using System;
using System.Xml;
using System.Reflection;
using System.IO;

namespace MyApp
{
  public class EmbeddedResourceResolver : XmlUrlResolver
  {
    public override object GetEntity(Uri absoluteUri,
      string role, Type ofObjectToReturn)
    {
      Assembly assembly = Assembly.GetExecutingAssembly();
      return assembly.GetManifestResourceStream("the.path.to.your.resource");
    }
  }
}

因为不允许您更改 XML,您的实施取决于嵌入资源在项目结构中的位置。

您可以在 XmlResolver 上找到更多信息 here

我的最终代码

注意:作为参考,我的两个嵌入式 XSD 都位于我的项目的根目录中

using System;
using System.Reflection;
using System.Xml;
using System.Xml.Schema;

namespace Example
{
    public class EmbeddedResourceResolver : XmlUrlResolver
    {
        public override object GetEntity(Uri absoluteUri, string role, Type ofObjectToReturn)
        {
            Assembly assembly = Assembly.GetExecutingAssembly();
            return assembly.GetManifestResourceStream("Example.Schema2.xsd");
        }
    }

    class Program
    {
        public static void Main()
        {
            XmlSchema schema1 = null;

            using (XmlTextReader xtr = new XmlTextReader(Assembly.GetExecutingAssembly().GetManifestResourceStream("Example.Schema1.xsd")))
            {
                schema1 = XmlSchema.Read(xtr, new ValidationEventHandler(XSDValidationEventHandler));
                xtr.Close();
            }

            XmlSchemaSet schemaSet = new XmlSchemaSet();

            schemaSet.XmlResolver = new EmbeddedResourceResolver();
            schemaSet.ValidationEventHandler += new ValidationEventHandler(XSDValidationEventHandler);
            schemaSet.Add(schema1);

            schemaSet.Compile();

            XmlSchema compiledSchema = null;

            foreach (XmlSchema schema in schemaSet.Schemas())
            {
                compiledSchema = schema;
            }

            Console.WriteLine("Finished");
            Console.ReadKey();
        }

        public static void XSDValidationEventHandler(object sender, ValidationEventArgs args)
        {
            Console.WriteLine(args.Message);
        }
    }
}