Validating XML Against a XSD Schema

S

Shailendra Batham

hi guys
I need your suggestions / opinion for doing this the right way.

I have a XML and a Schema for the same

What I want is when its validated against the schema, it should give custom errors saying what happened and where......

is it possible to do that ?

for eg. if the Attribute is missing or invalid in the following element <Watch ID="999d999">
then it should say ID attribute invalid for "Watch" Element.

Right now the validation works but the error returning our very vague, I need a way where I can customize the error or at least let the user know where the error is at what element and which attribute.

thanks,
Shailendra Batham
 
J

Jonathan Chong

What language do you use? Below is the sample code in C++:

Validating an XML Document Against an XML Schema Using C++
To validate an XML document file with an XML Schema definition language (XSD) schema file using C++, you load XML and XSD documents and create a schema cache as in the following example.

#include "stdio.h"

#import <msxml4.dll>
using namespace MSXML2;

int checkParseError(IXMLDOMParseErrorPtr pError);
void dump_com_error(_com_error &e);


int main(int argc, char* argv[])
{

CoInitialize(NULL);
try{

IXMLDOMParseErrorPtr pError;

// load the XML file
// ****** you need to use IXMLDOMDocument2 interface *********
IXMLDOMDocument2Ptr pXMLDoc;
HRESULT hr = pXMLDoc.CreateInstance(__uuidof(DOMDocument40));
pXMLDoc->async = VARIANT_FALSE;

hr = pXMLDoc->load("books.xml");

//check on the parser error
if(hr!=VARIANT_TRUE)
{
return checkParseError(pXMLDoc->parseError);
}

//load the XSD file
IXMLDOMDocumentPtr pXSDDoc;
hr = pXSDDoc.CreateInstance(__uuidof(DOMDocument40));
pXSDDoc->async = VARIANT_FALSE;

hr = pXSDDoc->load("books.xsd");

//check on the parser error
if(hr!=VARIANT_TRUE)
{
return checkParseError(pXSDDoc->parseError);
}

//create schemacache
IXMLDOMSchemaCollectionPtr pSchemaCache;
hr = pSchemaCache.CreateInstance(__uuidof(XMLSchemaCache40));
pXMLDoc->schemas = pSchemaCache.GetInterfacePtr();

//hook it up with XML Document
hr = pSchemaCache->add("urn:books", pXSDDoc.GetInterfacePtr());

//call validate
pError = pXMLDoc->validate();

if(pError->errorCode != S_OK)
{
_bstr_t parseError = _bstr_t("Error code: ")+ _bstr_t(pError->errorCode) +_bstr_t("\n") + _bstr_t("Reason: ")+ pError->Getreason();
MessageBox(NULL, (char*)parseError, "Parse Error",MB_OK);
return -1;
}
else
MessageBox(NULL,"Valiation succeeded", "Results",MB_OK);

}
catch(_com_error &e)
{
dump_com_error(e);
}
return 0;
}


int checkParseError(IXMLDOMParseErrorPtr pError)
{
_bstr_t parseError =_bstr_t("At line ")+ _bstr_t(pError->Getline()) + _bstr_t("\n")+ _bstr_t(pError->Getreason());
MessageBox(NULL,parseError, "Parse Error",MB_OK);
return -1;

}

void dump_com_error(_com_error &e)
{
printf("Error\n");
printf("\a\tCode = %08lx\n", e.Error());
printf("\a\tCode meaning = %s", e.ErrorMessage());
_bstr_t bstrSource(e.Source());
_bstr_t bstrDescription(e.Description());
printf("\a\tSource = %s\n", (LPCSTR) bstrSource);
printf("\a\tDescription = %s\n", (LPCSTR) bstrDescription);
}Input file: books.xml

<?xml version="1.0"?>
<x:catalog xmlns:x="urn:books">
<book id="bk101">
<author>Gambardella, Matthew</author>
<title>XML Developer's Guide</title>
<genre>Computer</genre>
<price>44.95</price>
<publish_date>2000-10-01</publish_date>
<description>An in-depth look at creating applications with XML.</description>
</book>
</x:catalog>
Input file: books.xsd

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="urn:books" xmlns:b="urn:books">

<xsd:element name="catalog" type="b:CatalogData"/>
<xsd:complexType name="CatalogData">
<xsd:sequence>
<xsd:element name="book" type="b:bookdata" minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>

<xsd:complexType name="bookdata">
<xsd:sequence>
<xsd:element name="author" type="xsd:string"/>
<xsd:element name="title" type="xsd:string"/>
<xsd:element name="genre" type="xsd:string"/>
<xsd:element name="price" type="xsd:float"/>
<xsd:element name="publish_date" type="xsd:date"/>
<xsd:element name="description" type="xsd:string"/>
</xsd:sequence>
<xsd:attribute name="id" type="xsd:string"/>
</xsd:complexType>
hi guys
I need your suggestions / opinion for doing this the right way.

I have a XML and a Schema for the same

What I want is when its validated against the schema, it should give custom errors saying what happened and where......

is it possible to do that ?

for eg. if the Attribute is missing or invalid in the following element <Watch ID="999d999">
then it should say ID attribute invalid for "Watch" Element.

Right now the validation works but the error returning our very vague, I need a way where I can customize the error or at least let the user know where the error is at what element and which attribute.

thanks,
Shailendra Batham
 
G

Guest

Hi Shailendra,

If you are coding in .Net,

Look at these:

System.Xml.Schema

ValidationEventHandler
ValidationEventArgs

XmlTextReader xmlreader = new XmlTextReader("test.xml");
XmlValidatingReader valid = new XmlValidatingReader(xmlreader);
valid.ValidationType = ValidationType.Schema;

Cheers.
 
S

Shailendra Batham

Thanks for the reply guys.

hey chua I am using C# and I am using the ValidationEventHandler, it works
fine but this is what error it returns

"The 'ID' attribute has an invalid value according to its data type. An
error occurred at , (2, 9)." string

can we do custom errors like what node's attribute had an error.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top