2016-01-20 92 views
0

我有一个验证针对XSD文档的XML文档,如下C#脚本:对XSD XML验证总是返回true

static bool IsValidXml(string xmlFilePath, string xsdFilePath) 
    { 

     XmlReaderSettings settings = new XmlReaderSettings(); 
     settings.Schemas.Add(null, xsdFilePath); 
     settings.ValidationType = ValidationType.Schema; 
     settings.Schemas.Compile(); 

     try 
     { 
      XmlReader xmlRead = XmlReader.Create(xmlFilePath, settings); 
      while (xmlRead.Read()) 
      { }; 
      xmlRead.Close(); 
     } 
     catch (Exception e) 
     { 
      return false; 
     } 

     return true; 
    } 

我一直在寻找一些MSDN文章和问题之后,这个编译在这里,这是解决方案。它确实正确地验证了XSD形成良好(如果我弄乱了文件,则返回false),并检查XML是否形成良好(当与之混淆时也返回false)。

我也试过以下,但它完全一样的事情:

static bool IsValidXml(string xmlFilePath, string xsdFilePath) 
    { 

     XDocument xdoc = XDocument.Load(xmlFilePath); 
     XmlSchemaSet schemas = new XmlSchemaSet(); 
     schemas.Add(null, xsdFilePath); 

     try 
     { 
      xdoc.Validate(schemas, null); 
     } 
     catch (XmlSchemaValidationException e) 
     { 
      return false; 
     } 

     return true; 
    } 

我甚至拉到一个完全随机的XSD从互联网和它扔进两个脚本,它仍然验证双方。我在这里错过了什么?

在SSIS作业中使用.NET 3.5。

+1

你还没有提供任何细节,但是如果你使用随机模式验证XML,那么这可能是预期的。如果文档在模式中没有任何匹配的元素,您将得到最好的警告。 –

+4

[使用XSD正确验证XML文档]可能的副本(http://stackoverflow.com/questions/16755058/validating-xml-documents-with-xsd-correctly) –

+1

检查XML文档中的名称空间是否与正在由模式定位。可能有助于发布您试图验证的模式和xml文件的示例 – SCB

回答

0

在.NET中,您必须检查自己验证器是否实际匹配模式组件;如果没有,则不会抛出异常,因此您的代码将无法按预期工作。

的匹配是指以下的一种或两种:

  • 有模式中的一个全局元素具有限定名称设置是一样的XML文档元素的限定名。
  • 文档元素具有xsi:type属性,这是一个限定名称,指向模式集中的全局类型。

在流模式下,您可以轻松进行此项检查。这个伪实物-的代码应该给你一个想法(处理未显示错误等):

using (XmlReader reader = XmlReader.Create(xmlfile, settings)) 
{ 
    reader.MoveToContent(); 
    var qn = new XmlQualifiedName(reader.LocalName, reader.NamespaceURI); 
    // element test: schemas.GlobalElements.ContainsKey(qn); 
    // check if there's an xsi:type attribute: reader["type", XmlSchema.InstanceNamespace] != null; 
    // if exists, resolve the value of the xsi:type attribute to an XmlQualifiedName 
    // type test: schemas.GlobalTypes.ContainsKey(qn); 
    // if all good, keep reading; otherwise, break here after setting your error flag, etc. 
} 

您也可以考虑其表示已被分配到一个节点后架构验证信息集的XmlNode.SchemaInfo作为模式验证的结果。我会测试不同的条件,并看看它如何适用于您的方案。建议第一种方法减少DoS攻击中的攻击面,因为它是检测完全伪造有效负载的最快方法。