使用带有包含的XSD

这是一个XSD:

      

这是第二个包含上述XSD的XSD:

          

我需要将(第二个)XSD读入C#并且:

  1. 检查它是否是有效的XSD,并且
  2. validation文件。

下面是一些在架构中读取的C#:

  XmlSchemaSet schemaSet = new XmlSchemaSet(); foreach (string sd in Schemas) { using (XmlReader r = XmlReader.Create(new FileStream(sd, FileMode.Open))) { schemaSet.Add(XmlSchema.Read(r, null)); } } schemaSet.CompilationSettings = new XmlSchemaCompilationSettings(); schemaSet.Compile(); 

.Compile()失败,因为“Type’a:TheSimpleType’未声明,或者不是简单类型。”

但是,它适用于:

  • 命名空间将从架构中删除,或
  • 命名空间被添加到include中。

问题是:如何在不编辑架构的情况下让C#接受它?

我怀疑问题是虽然我已经将两个架构放入XmlSchemaSet中,但我仍然需要告诉C#一个被包含在另一个中,即它没有为自己解决问题。 实际上,如果我只告诉XmlSchemaSet关于主XSD(而不是include)(两者都没有(或带有)名称空间)那么“Type”TheSimpleType’未声明,或者不是简单类型。“

因此,这似乎是一个关于解决的问题包括:如何?!

问题在于打开架构以便在线读取的方式:

 XmlReader.Create(new FileStream(sd, FileMode.Open) 

在我看到包含文件的路径是如何解析之前,我必须编写自己的XmlResolver :它来自可执行文件的目录,而不是来自父模式的目录。 问题是父模式没有设置其BaseURI。 以下是必须打开架构的方法:

 XmlReader.Create(new FileStream(pathname, FileMode.Open, FileAccess.Read),null, pathname) 

您可以使用XmlSchema.Includes将它们链接在一起。 然后,您只需要将主模式添加到模式集:

 var includeSchema = XmlSchema.Read(XmlReader.Create(...), null); var mainSchema = XmlSchema.Read(XmlReader.Create(...), null); var include = new XmlSchemaInclude(); include.Schema = includeSchema; mainSchema.Includes.Add(include); var schemaSet = new XmlSchemaSet(); schemaSet.Add(mainSchema); schemaSet.Compile(); 

试试这个:D

 public static XmlSchema LoadSchema(string pathname) { XmlSchema s = null; XmlValidationHandler h = new XmlValidationHandler(); using (XmlReader r = XmlReader.Create(new FileStream(pathname, FileMode.Open))) { s = XmlSchema.Read(r, new ValidationEventHandler(h.HandleValidationEvent)); } if (h.Errors.Count > 0) { throw new Exception(string.Format("There were {1} errors reading the XSD at {0}. The first is: {2}.", pathname, h.Errors.Count, h.Errors[0])); } return s; } public static XmlSchema LoadSchemaAndResolveIncludes(string pathname) { FileInfo f = new FileInfo(pathname); XmlSchema s = LoadSchema(f.FullName); foreach(XmlSchemaInclude i in s.Includes) { XmlSchema si = LoadSchema(f.Directory.FullName + @"\" + i.SchemaLocation); si.TargetNamespace = s.TargetNamespace; i.Schema = si; } return s; } public static List Validate(string pathnameDocument, string pathnameSchema) { XmlSchema s = LoadSchemaAndResolveIncludes(pathnameSchema); XmlValidationHandler h = new XmlValidationHandler(); XmlDocument x = new XmlDocument(); x.Load(pathnameDocument); x.Schemas.Add(s); s.Compile(new ValidationEventHandler(h.HandleValidationEvent)); x.Validate(new ValidationEventHandler(h.HandleValidationEvent)); return h.Errors; } 

特别注意si.TargetNamespace = s.TargetNamespace;

显然,这假设包含被指定为相对于包含它们的模式的文件路径。

这是我写的处理xsdvalidation的方法。 希望这对某人有所帮助。

  ///  /// Ensure all xsd imported xsd documented are in same folder as master xsd ///  public XsdXmlValidatorResult Validate(string xmlPath, string xsdPath, string xsdNameSpace) { var result = new XsdXmlValidatorResult(); var readerSettings = new XmlReaderSettings {ValidationType = ValidationType.Schema}; readerSettings.ValidationFlags |= XmlSchemaValidationFlags.ProcessInlineSchema; readerSettings.ValidationFlags |= XmlSchemaValidationFlags.ProcessSchemaLocation; readerSettings.Schemas.Add(null, xsdPath); readerSettings.ValidationEventHandler += (sender, args) => { switch (args.Severity) { case XmlSeverityType.Warning: result.Warnings.Add(args.Message); break; case XmlSeverityType.Error: result.IsValid = false; result.Warnings.Add(args.Message); break; } }; var reader = XmlReader.Create(xmlPath, readerSettings); while (reader.Read()) { } return result; }