#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <libxml/tree.h>
#include <libxml/xmlschemas.h>


static void
xml_structured_err(void *user_data, xmlError *error)
{
	fprintf(stderr, "%s:%d:%d: %s\n",
		error->file ? error->file : "<null>",
		error->line,
		error->int2,
		error->message);
}


int
main(int argc, char **argv)
{
	char		*xml_filename;
	char		*xsd_filename = NULL;
	xmlDoc		*doc;
	xmlSchema	*schema;
        xmlSchemaParserCtxt *spctxt;
        xmlSchemaValidCtxt *valctxt;
	xmlParserInputBuffer *parser_input;
	xmlSAXHandler   sax;
	int		sax_result;

	if (argv[1] == NULL || argv[2] == NULL) {
		fprintf(stderr, "usage: %s xml_filename xsd_filename\n",
			argv[0]);
		exit(1);
	}
	xml_filename = argv[1];
	xsd_filename = argv[2];

	spctxt = xmlSchemaNewParserCtxt(xsd_filename);
	schema = xmlSchemaParse(spctxt);
	xmlSchemaFreeParserCtxt(spctxt);
	if (schema == NULL) {
		fprintf(stderr, "failed to load xsd schema %s\n",
			xsd_filename);
		exit(3);
	}

	valctxt = xmlSchemaNewValidCtxt(schema);
	xmlSchemaSetValidStructuredErrors(valctxt, xml_structured_err, NULL);
	xmlSchemaValidateSetFilename(valctxt, xml_filename);

	parser_input = xmlParserInputBufferCreateFilename(xml_filename,
		XML_CHAR_ENCODING_NONE);
	if (parser_input == NULL) {
		fprintf(stderr, "xmlParserInputBufferCreateFilename %s failed\n",
			xml_filename);
		exit(2);
	}
	memset(&sax, 0, sizeof(sax));
	sax.initialized = XML_SAX2_MAGIC;
	sax_result = xmlSchemaValidateStream(valctxt, parser_input,
		XML_CHAR_ENCODING_NONE, &sax, NULL);

	xmlSchemaFreeValidCtxt(valctxt);
	if (sax_result != 0) {
		fprintf(stderr, "schema validation error %d\n", sax_result);
	}

	exit(0);
}
