在找到匹配项之前,针对多个模式验证未知的xml

时间:2013-03-26 09:43:43

标签: c# xml xsd linq-to-xml

我已将xml发送到网页,我想对几个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;
  });

任何人都可以提供帮助,上面是我到目前为止拼凑在一起的内容,它目前引发了一个错误&#39; System.Xml.Schema.XmlSchemaValidationException:全局元素&#39; interface&#39;已经宣布&#39;

有没有办法让返回哪种架构价值成功?

2 个答案:

答案 0 :(得分:4)

首先,您必须弄清楚哪些XSD文件可以放在一个文件集中。您收到的错误告诉您,相同的元素“接口”的定义来自两个或多个不同的基URI。

如果你想动态地确定这些集合,那么你需要做一些工作。这是可能的,但这不是微不足道的。这取决于XSD文件是否使用合成(include / import / redefine)。如果他们不这样(简单方案),那么为了将XSD文件放在一起你必须单独加载每个XSD文件,建立一个所有全局定义的内容(类型,元素,组,属性,属性组)的索引然后放入将那些集合中的那些集合在一起,使得给定集合中的任何一对单独的XSD成员,交集集是空的。构建集合的策略取决于许多因素,性能和覆盖范围仅为两个。基于这个简单的案例,您可以看到组合如何变得重要,因为现在即使交集不为空,如果公共内容来自相同的URI,则所有意图都被视为空。

QTAssistant(我与之相关)有一个完整的引擎来处理上述内容,以便在“收获”任意XSD时为其XML Schema Refactoring引擎设置XML Schema源集(或集合)用于分析,验证等的内容

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

如果您想根据您的问题处理它,那么只需循环遍历如上构造的一组模式集。

提出如何手动找出最佳集合的策略的最佳方法可能是可视化XSD文件之间的关系。下面是我如何通过我可以使用的工具看到它的例子,来自SO的另一篇文章。

enter image description here

答案 1 :(得分: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;
    }
}