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

时间:2012-07-19 08:53:09

标签: c# xml xsd

我正在尝试在保存之前验证我在代码中创建的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);
       }
   } 

EDIT 示例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>

2 个答案:

答案 0 :(得分:1)

我找到了解决方案。我必须在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 :(得分:0)

这是我用于使用模式验证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} \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();
    }
}