Introduction
This is a simple command prompt application to validate XML against XSD, i.e., XML schema file.
The intention being a new development is there are situations like running a make file to build a huge package that might include XML files at some point and need to be validated. Those XML files may require a specific rule or data type which checks item’s value range or in other words, user specific datatype
.
Background
This is one such tool, exe can be used to make script during package build where validation is needed.
Implemented in C# solution as command based, and C# class DLL for core validation function and for log file. For error logging, log4net.dll is used which is freeware, reason being log4net enables logging simple.
The Code
ValidationUtils.dll - This includes the core implementation class and this DLL is added to solution‘s References.
public bool OpenXmlFileUtils(string xml_path)
{
if (xmlPath != xml_path)
xmlPath = xml_path;
try
{
reader = XmlReader.Create(xml_path, readerSettings);
xmlDoc.Load(xml_path);
CloseXmlFile(reader);
bResult = true;
}
catch (Exception)
{
bResult = false;
}
return bResult;
}
public void ValidateXMLUtils(string testString, int iCount)
{
nErrors = 0;
try
{
XmlReaderSettings rs = new XmlReaderSettings();
rs.ValidationType = ValidationType.Schema;
rs.ValidationFlags |= XmlSchemaValidationFlags.ProcessSchemaLocation |
XmlSchemaValidationFlags.ReportValidationWarnings;
rs.ValidationEventHandler += new ValidationEventHandler(ValidationEventHandlerUtils);
rs.Schemas.Add(null, XmlReader.Create(testString));
xmlValidatingReader = XmlReader.Create(xmlPath, rs);
...
}
void ValidationEventHandlerUtils(object sender, ValidationEventArgs e)
{
validationCalledCount++;
if (e.Severity == XmlSeverityType.Warning)
{
validationResultStr = e.Message;
}
…
}
Logging class implementation (wrapper to log4net
APIs):
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using log4net;
namespace ValidationUtils
{
public class LogFile
{
public bool results = false;
private static readonly ILog logger =
LogManager.GetLogger(typeof(LogFile));
public static LogFile logfile_instance;
public LogFile()
{
log4net.Config.XmlConfigurator.Configure();
}
public static LogFile cpeLogFileInstance
{
get
{
if (logfile_instance == null)
{
logfile_instance = new LogFile();
}
return logfile_instance;
}
}
…
}
Example XML and XSD files used to capture output screenshot:
XML
="1.0"="UTF-8"
<shiporder orderid="150">
<orderperson>Raghavendra Hosad</orderperson>
<shipto>
<name>Raghavendra Hosad</name>
<address>Green Park 55</address>
<city>10 HYD</city>
<country>India</country>
</shipto>
<item>
<title>The Da Vinci Code</title>
<note>Special Edition</note>
<quantity>1</quantity>
<price>8.50</price>
</item>
<item>
<title>Harry Potter and the Goblet of Fire</title>
<quantity>1</quantity>
<price>12.30</price>
</item>
</shiporder>
XSD
="1.0"="utf-8"
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="shiporder">
<xs:complexType>
<xs:sequence>
<xs:element name="orderperson" type="xs:string" />
<xs:element name="shipto">
<xs:complexType>
<xs:sequence>
<xs:element name="name" type="xs:string" />
<xs:element name="address" type="xs:string" />
<xs:element name="city" type="xs:string" />
<xs:element name="country" type="xs:string" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element maxOccurs="unbounded" name="item">
<xs:complexType>
<xs:sequence>
<xs:element name="title" type="xs:string" />
<xs:element minOccurs="0" name="note" type="xs:string" />
<xs:element name="quantity" type="xs:unsignedByte" />
<xs:element name="price" type="xs:decimal" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="orderid" type="xs:unsignedByte" use="required" />
</xs:complexType>
</xs:element>
<xs:simpleType name="quantityType">
<xs:annotation>
<xs:documentation>carrierIndex range checking.</xs:documentation>
</xs:annotation>
<xs:restriction base="xs:unsignedByte">
<xs:minInclusive value="2"/>
<xs:maxInclusive value="4"/>
</xs:restriction>
</xs:simpleType>
</xs:schema>
Result
- When validation is success.
- When there is validation error.
LogFile.log
A logfile is getting generated at system path C:\Users\<name>\AppData\Local\SchemaValidatorCmdTool\LogFile.log
2017-11-25 1:8:26,972 [9] INFO -------------------------------------------------------------
2017-11-25 1:8:26,979 [9] ERROR The 'quantity' attribute is invalid
2017-11-25 1:8:26,979 [9] WARN The value '1' is invalid according to its datatype 'quantityType'
2017-11-25 1:8:26,979 [9] WARN The MinInclusive constraint failed.
2017-11-25 1:8:26,979 [9] INFO Total item failed count : 1
2017-11-25 1:8:26,979 [9] INFO Total item pass count : 15
2017-11-25 1:8:26,979 [9] INFO -------------------------------------------------------------
Conclusion
I believe choosing a particular schema validator tool depends upon one's requirement. There are GUI implementations of such tools available but as long as we are not bothered about editing an item and need to include during make build, I think this tool (SchemaValidatorCmdTool
) is handy and also a LogFile.log generating which can be used for examining additional fail item information.
History
- 27th November, 2017: Initial version