2016-01-20 97 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攻擊中的攻擊面,因爲它是檢測完全僞造有效負載的最快方法。