2012-07-19 31 views
0

我想在我保存之前驗證在代碼中創建的XML文檔。但是,即使我輸入了不正確的值,我的代碼始終通過驗證,沒有問題。代碼有什麼問題?爲什麼XmlDocument.validate錯誤地驗證了具有空名稱空間的無效xml文檔?

private XmlDocument xmlDocChanges = new XmlDocument(); 
    public void Validate() 
    { 
     xmlDocChanges.Schemas.Add("http://www.w3.org/2001/XMLSchema", "xsd/Customization.xsd"); 
     ValidationEventHandler eventHandler = new ValidationEventHandler(ValidationCallBack); 
     xmlDocChanges.Validate(eventHandler); 
    } 
    public void ValidationCallBack (object sender, ValidationEventArgs args) 
    { 
     if(args.Severity == XmlSeverityType.Error || args.Severity == XmlSeverityType.Warning) 
     { 
      throw new Exception(args.Exception.Message); 
     } 
    } 

編輯 示例XSD。

<?xml version="1.0" encoding="utf-8"?> 
<xs:schema 
    attributeFormDefault="unqualified" 
    elementFormDefault="qualified" 
    xmlns:xs="http://www.w3.org/2001/XMLSchema"> 

    <xs:complexType name="FirstNode"> 
    <xs:annotation> 
     <xs:documentation>First node</xs:documentation> 
    </xs:annotation> 
    <xs:attribute name="Identifier" type="xs:string" use="required" /> 
    <xs:attribute name="Bool" type="xs:boolean" use="optional" /> 
    </xs:complexType> 
</xs:schema> 

XML

<Customizations FormatVersion="1" xsi:noNamespaceSchemaLocation="Customization.xsd"> 
    <Customization> 
    <Application name="App"> 
     <FirstNode Identifier="one" Bool="NoValue"></FirstNode> 
    </Application> 
    </Customization> 
</Customizations> 
+0

這些方法是否被執行過?如果這樣的話提供你驗證的schema和xml。 – Rafal 2012-07-19 09:00:49

+0

您可以爲使用中的XSD和XML文件添加示例嗎? – AksharRoop 2012-07-19 09:01:22

+0

正在執行驗證,並且只有在驗證出現問題時才執行ValidationCallBack。 – Frozendragon 2012-07-19 09:18:22

回答

1

我找到了解決方案驗證XML的方法。我必須在add方法中發送一個空的名稱空間參數。

public void Validate() 
    { 
     xmlDocChanges.Schemas.Add("", "xsd/Customization.xsd"); 
     ValidationEventHandler eventHandler = new ValidationEventHandler(ValidationCallBack); 
     xmlDocChanges.Validate(eventHandler); 
    } 
    public void ValidationCallBack (object sender, ValidationEventArgs args) 
    { 
     if(args.Severity == XmlSeverityType.Error || args.Severity == XmlSeverityType.Warning) 
     { 
      throw new Exception(args.Message); 
     } 
    } 
+1

您的架構沒有'targetNamespace',所以最初的'xmlDocChanges.Schema.Add(「http://www.w3.org/2001/XMLSchema」,...)'剛剛綁定了一個您沒有用到的命名空間'Customization.xsd'模式。模式中類型的'targetNamespace'必須與xml中類型的名稱空間相匹配,當然,您使用'XmlDocument.Schemas.Add()'綁定的名稱空間' – Alberto 2014-07-18 11:35:14

0

下面是我用一個架構

public static Tuple<bool, string> ValidateXml(string xmlSchemaFile, string sourceXml) { 

     var internalValidationErrors = new XmlSchemaValidationErrorCollection(); 
     ValidationEventHandler handler = (sender, args) => internalValidationErrors.Add(args); 
     var settings = new XmlReaderSettings { ValidationType = ValidationType.Schema }; 

     try { 
      // Set the validation settings. 
      settings = new XmlReaderSettings { ValidationType = ValidationType.Schema }; 
      settings.ValidationFlags |= XmlSchemaValidationFlags.ProcessInlineSchema; 
      settings.ValidationFlags |= XmlSchemaValidationFlags.ProcessSchemaLocation; 
      settings.ValidationFlags |= XmlSchemaValidationFlags.ReportValidationWarnings; 
      settings.ValidationEventHandler += handler; 

      using(var reader = XmlReader.Create(xmlSchemaFile)) { 
       settings.Schemas.Add(null, reader); 
      } 

      if(settings.Schemas.Count == 0) 
       return Tuple.Create(false, "Missing schema file."); 

      // Create the XmlReader object for xml 
      using(var reader = XmlReader.Create(sourceXml, settings)) { 
       // Parse the file. 
       while(reader.Read()) {} 
      } 

      var validationErrors = internalValidationErrors; 

      return Tuple.Create(validationErrors.Any(), validationErrors.ToString()); 
     } 
     finally { 
      settings.ValidationEventHandler -= handler; 
     } 
    } 

public class XmlSchemaValidationErrorCollection : List<ValidationEventArgs> 
{ 
    internal XmlSchemaValidationErrorCollection() 
    { } 

    public override string ToString() 
    { 
     var builder = new StringBuilder(); 

     foreach (var validationError in this) 
     { 
      builder.Append("-Validation Error-"); 
      builder.AppendFormat("Message: {0} \r\n", validationError.Message); 
      builder.AppendFormat("Severity: {0} \r\n", Enum.GetName(typeof(XmlSeverityType), validationError.Severity)); 
      builder.AppendFormat("Exception: {0} \r\n", validationError.Exception.GetDeepMessage()); 
      builder.Append("\r\n"); 
     } 

     return base.ToString(); 
    } 
} 
+0

謝謝,但是代碼假設XML存在於磁盤上,我想在保存XML文檔之前進行驗證。 – Frozendragon 2012-07-19 09:15:51

+0

您可以更改方法從流中讀取xml,以便從內存流中讀取等。 – stevethethread 2012-07-19 09:21:16

+0

您是否認爲可以使用MemoryStream顯示示例我不確定您應該如何使用它。 – Frozendragon 2012-07-19 11:54:50

相關問題