根据多个模式验证未知的XML,直到找到匹配项。

4

我收到了一个XML文件并想要对其进行多个XSD的验证,直到该文件能够通过验证。当文件能够通过验证时,我将根据所使用的XSD确定XML文件的类型。

  List<string> xsdList = new List<string>();

  xsdList.Add(_path + @"Handlers\DeviceSpecificHandlers\Schemas\Enquiry.xsd");
  xsdList.Add(_path + @"Handlers\DeviceSpecificHandlers\Schemas\FingerDeleted.xsd");
  xsdList.Add(_path + @"Handlers\DeviceSpecificHandlers\Schemas\Heartbeat.xsd");
  xsdList.Add(_path + @"Handlers\DeviceSpecificHandlers\Schemas\Validation.xsd");

  XmlSchemaSet schemas = new XmlSchemaSet();

  foreach (string schema in xsdList)
  {
    var reader = new StringReader(File.ReadAllText(schema));
    schemas.Add("", XmlReader.Create(reader));
  }

  request.Validate(schemas, (o, e) =>
  {
    match = false;
  });

有人能帮忙吗?上面是我目前拼凑出来的代码,目前会抛出一个错误:“System.Xml.Schema.XmlSchemaValidationException:全局元素'interface'已经被声明”

有没有一种方法可以返回模式验证成功的结果?

2个回答

5
首先,您需要确定哪些XSD文件可以放在一个文件集中。您收到的错误提示告诉您,相同的元素“interface”具有来自两个或多个不同基本URI的定义。
如果您想动态确定这些集合,则需要进行一些工作。虽然可能,但并不容易。它取决于XSD文件是否使用组合(包括/导入/重新定义)。如果它们不是(简单的情况),则为了将XSD文件放在一起,您必须单独加载每个XSD文件,构建所有全局定义内容(类型、元素、组、属性、属性组)的索引,然后将这些内容放在集合中,使得任何一对单独的XSD成员的交集集为空。构建集合的策略取决于许多因素,性能和覆盖率仅是其中两个。基于这种简单的情况,您可以看到组合变得重要,因为现在即使交集不为空,如果公共内容来自同一个URI,则可以认为它是空的。

QTAssistant(我与之相关)有一个完整的引擎来处理上述问题,以便为其XML Schema重构引擎设置XML Schema源集(或集合),当“收集”任意XSD内容进行分析、验证等。

一旦你弄清楚了这些集合,就必须对这些模式的组成做出假设。换句话说,什么构成有效的XML文档元素集(有时并非所有全局元素定义都是有效的文档元素),以及应该为每个文档元素使用哪个模式集。很明显,你必须以某种方式处理这个问题,因为你有重复的元素。

如果你想按照你的问题处理它,那么只需简单地循环遍历如上构建的模式集的集合即可。

手动确定最佳集合的策略的最佳方法可能是通过可视化您的XSD文件之间的关系来实现的。下面是我使用我拥有的工具从SO的另一篇文章中看到的示例。

enter image description here


谢谢,这解释了一切。我对XSD验证的理解完全错误了。 - DavidB

1

来自 http://msdn.microsoft.com/en-us/library/fe6y1sfe(v=vs.110).aspx:

"XmlSchemaSet 中的架构通过 XmlSchemaSet 的 Compile 方法编译成一个逻辑架构。"

因此,要针对多个单独的架构进行验证,您应该为每个 XSD 创建一个 XmlSchemaSet

然后,您可以执行以下操作:

bool xmlIsValid = true;
XmlSchemaSet validatingSchema;
foreach (XmlSchemaSet schema in schemas) {
    xml.Validate(schema, (o, e) => { xmlIsValid = false; });
    if (xmlIsValid) {
        validatingSchema = schema;
        break;
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接