Kailayla
Kailayla

Reputation: 323

Invalid XML comes out as valid

I have made an XML schema to validate incoming xml files to validate if they are an Error or not. I have some code that should return true when an xml file is valid, or false when it's not. I have also made two XML files, one of which is valid, the other invalid. However, my code returns true for both of them, aka considers them both valid. How come? Where did I go wrong?

The schema:
XMLSchemaError.xsd

<?xml version="1.0" encoding="utf-8"?>
<xs:schema id="XMLSchemaError"
    targetNamespace="http://tempuri.org/XMLSchemaError.xsd"
    elementFormDefault="qualified"
    xmlns="http://tempuri.org/XMLSchemaError.xsd"
    xmlns:mstns="http://tempuri.org/XMLSchemaError.xsd"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
>
  <xs:element name="Error">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="Server_ID" type="xs:integer" />
        <xs:element name="Prioritizing" type="xs:token" />
        <xs:element name="Type" type="xs:token" />
        <xs:element name="Thrown_by" type="xs:token" />
        <xs:element name="Code" type="xs:string" />
        <xs:element name="Text" type="xs:string" />
        <xs:element name="Time_occured" type="xs:dateTime" />
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>

Code to validate the XML file:
XMLValidation.cs

private bool isValid = false;       

public bool checkValid(string fileName)
{
    try
    {
        var reader = XmlReader.Create("../../XMLFiles/" + fileName);
        XmlDocument doc = new XmlDocument();
        doc.PreserveWhitespace = true;
        doc.Load(reader);
        doc.Schemas.Add(null, "../../Model/XMLSchemaError.xsd");
        doc.Validate(ValidationCallBack);
        isValid = true;
    }
    catch
    {
        isValid = false;
    }            
    System.Diagnostics.Debug.WriteLine("Check: " + isValid);
    return isValid;
}

private void ValidationCallBack(object sender, ValidationEventArgs e)
{
    throw new Exception();
}

The 2 XML files to validate:
Valid.xml

<?xml version="1.0" encoding="UTF-8"?>
<Error>
    <Server_ID>4</Server_ID>
    <Prioritizing>major</Prioritizing>
    <Type>test error</Type>
    <Thrown_by>test program</Thrown_by>
    <Code></Code>
    <Text></Text>
    <Time_occurred>2016-02-9T12:34:56.7890</Time_occurred>
</Error>

Invalid.xml

<?xml version="1.0" encoding="UTF-8"?>
<note>
  <to>Tove</to>
  <from>Jani</from>
  <heading>Reminder</heading>
  <body>Don't forget me this weekend!</body>
</note>

Upvotes: 1

Views: 1355

Answers (1)

Peter Duniho
Peter Duniho

Reputation: 70652

As commenter Damien_The_Unbeliever points out, since your XML doesn't claim to contain any elements that are validated by the schema in question, both documents trivially pass validation. There's nothing in them to validate.

There are a variety of ways to correct the situation. The simplest is to just add a default XML namespace to the root element. E.g.:

<?xml version="1.0" encoding="UTF-8"?>
<note xmlns="http://tempuri.org/XMLSchemaError.xsd">
  <to>Tove</to>
  <from>Jani</from>
  <heading>Reminder</heading>
  <body>Don't forget me this weekend!</body>
</note>

Having done that, the above XML now will fail validation according to your schema.

If you were to do the same thing to the "valid" XML, you would find that it too fails validation. This is for two reasons:

  1. The schema misspells the word "occurred", while the XML does not. This can be fixed either by correcting the spelling the schema or by using the misspelling in the XML.
  2. The XML has an incorrectly formatted dateTime value. The day-of-month field is specified using only a single digit, but the XML format requires two digits for both the month and day-of-month fields.

An actual valid XML, given the schema you've provided, would look like this:

<?xml version="1.0" encoding="UTF-8"?>
<Error xmlns="http://tempuri.org/XMLSchemaError.xsd">
    <Server_ID>4</Server_ID>
    <Prioritizing>major</Prioritizing>
    <Type>test error</Type>
    <Thrown_by>test program</Thrown_by>
    <Code></Code>
    <Text></Text>
    <Time_occured>2016-02-09T12:34:56.7890</Time_occured>
</Error>

(I've opted to misspell the element name in the XML, rather than fixing the schema, just because it simplifies the example XML required in this answer :) ).

Upvotes: 2

Related Questions