Dragon Creature
Dragon Creature

Reputation: 1995

Why does XmlDocument.validate incorrectly validate an invalid xml document with empty namespaces?

I'm trying to validate a XML document I'm creating in the code before i save it. However my code always pass through the validation with no problem even when i input incorrect value on purpose. What is the problem with the code?

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 Example 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>

Upvotes: 2

Views: 2603

Answers (2)

Dragon Creature
Dragon Creature

Reputation: 1995

I found a solution. I had to send a empty namespace parameter in the add method.

    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);
        }
    }

Upvotes: 1

stevethethread
stevethethread

Reputation: 2524

Here's a method I use for validating xml with a schema

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();
    }
}

Upvotes: 0

Related Questions