I have created a library to validate the XML file with the XSD file using XmlReaderSettings. It works fine until the user fills data in the XSD file then changes XSD extension to XML and uses the library to validate them, and that file passes the validation. (Although it's not a correct way to create the XML file, they have done it that way!)
So I want to know how does XmlReaderSettings work? And how to check that the XML file is not the XSD file?
Here is my code:
public static class XmlValidator
{
/// <summary>
/// Basic Validation of DA application.
/// Validate xml file with xsd file.
/// : return list of errors from validation, return empty list if no error occur.
/// </summary>
/// <param name="pathXml">Xml file path.</param>
/// <param name="pathXsd">Xsd file path.</param>
/// <returns>Return list of errors from validation, return empty list if no error occur.</returns>
public static List<string> Validate(string pathXml, string pathXsd, Action<DAStatus> callBack = null)
{
if (string.IsNullOrWhiteSpace(pathXml) || string.IsNullOrWhiteSpace(pathXsd))
{
throw new ArgumentException("Null or Empty are detected.");
}
else if (Path.GetExtension(pathXml).ToLower() != ".xml")
{
throw new InvalidFileTypeException(pathXml, ".xml");
}
else if (Path.GetExtension(pathXsd).ToLower() != ".xsd")
{
throw new InvalidFileTypeException(pathXsd, ".xsd");
}
List<string> errorList = new List<string>();
using (var fileStream = File.OpenRead(pathXml))
{
XmlReaderSettings settings = new XmlReaderSettings();
settings.Schemas.Add(null, pathXsd);
settings.ValidationType = ValidationType.Schema;
settings.ValidationEventHandler += (sender, e) => XMLReaderValidateHandler(e, errorList);
XmlReader xml = XmlReader.Create(fileStream, settings);
long lastPosition = 0;
long[] percent = { 0, 0 };
DAStatus progress = new DAStatus();
while (xml.Read())
{
// read and validate xml by xsd.
// Add callBack
if (callBack != null)
{
lastPosition = fileStream.Position;
percent[1] = Math.Min(100, (100 * lastPosition / fileStream.Length));
if (percent[0] < percent[1])
{
percent[0] = percent[1];
progress.ProgressPercent = percent[0];
callBack(progress);
}
}
}
}
return errorList;
}
private static void XMLReaderValidateHandler(ValidationEventArgs e, List<string> errorList)
{
errorList.Add(e.Message);
}
}
Update: I don't think my question is duplicate to the question that you guys refer because from my understanding that question is about automatically use the XSD file from the specific location to validate the XML, but my question is more like a user-error from creating the XML file in a wrong way. (Normally they should create the XML file in the right way but they want me to validate the XSD-XML file instead.)
The user has already sent me the example of their XML file created by changing the XSD file so I can provide the example.
Normally the XSD element looks like this:
<xs:element name="address" type="M_Address" />
And they change the element like this (Also change the file extension to .xml):
<xs:element name="test district" type="M_Address" />