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

时间:2015-11-02 11:36:03

标签: c# xml xsd

我正在尝试将2个嵌入式XSD编译成单个XSD文件,但我收到错误“无法解析'schemaLocation'属性”。我不确定如何解决这个问题,但我猜测它的命名空间有些如何。

Schema1.xsd对Schema2.xsd执行xsd:include

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内容或将其更改为不是嵌入式资源。

任何问题随时可以提出

由于

凯尔

1 个答案:

答案 0 :(得分:1)

当您使用嵌入式文件时,默认的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();
}

&#39; EmbeddedResourceResolver&#39;不是现有的Framework类,但可以由您自己创建。您可以在下面找到参考实现。

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);
        }
    }
}
相关问题