2015-11-02 27 views
0

我想將2個嵌入式XSD編譯成單個XSD文件,但我收到錯誤」無法解析'schemaLocation'屬性「。我不確定如何解決這一點,但我猜測它的命名空間一些如何。編譯兩個嵌入式XSD:錯誤「無法解析'schemaLocation'屬性

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內容或將其更改爲不被嵌入的資源。

任何問題隨時問

感謝

凱爾

回答

0

當你使用嵌入文件,默認的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'不是現有的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); 
     } 
    } 
}