为什么XmlDocument.validate错误地验证了具有空命名空间的无效xml文档



我试图在保存代码之前验证我在代码中创建的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>

我找到了一个解决方案。我不得不在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);
        }
    }

以下是我使用模式验证xml的方法

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} rn", validationError.Message);
            builder.AppendFormat("Severity: {0} rn", Enum.GetName(typeof(XmlSeverityType), validationError.Severity));
            builder.AppendFormat("Exception: {0} rn", validationError.Exception.GetDeepMessage());
            builder.Append("rn");
        }
        return base.ToString();
    }
}

最新更新