xmlSchemaFacetErr(xmlSchemaAbstractCtxtPtr actxt,
		  xmlParserErrors error,
		  xmlNodePtr node,
		  const xmlChar *value,
		  unsigned long length,
		  xmlSchemaTypePtr type,
		  xmlSchemaFacetPtr facet,
		  const char *message,
		  const xmlChar *str1,
		  const xmlChar *str2)
{
    xmlChar *str = NULL, *msg = NULL;
    xmlSchemaTypeType facetType;
    int nodeType = xmlSchemaEvalErrorNodeType(actxt, node);

    xmlSchemaFormatNodeForError(&msg, actxt, node);
    if (error == XML_SCHEMAV_CVC_ENUMERATION_VALID) {
	facetType = XML_SCHEMA_FACET_ENUMERATION;
	/*
	* If enumerations are validated, one must not expect the
	* facet to be given.
	*/
    } else
	facetType = facet->type;
    msg = xmlStrcat(msg, BAD_CAST "[");
    msg = xmlStrcat(msg, BAD_CAST "facet '");
    msg = xmlStrcat(msg, xmlSchemaFacetTypeToString(facetType));
    msg = xmlStrcat(msg, BAD_CAST "'] ");
    if (message == NULL) {
	/*
	* Use a default message.
	*/
	if ((facetType == XML_SCHEMA_FACET_LENGTH) ||
	    (facetType == XML_SCHEMA_FACET_MINLENGTH) ||
	    (facetType == XML_SCHEMA_FACET_MAXLENGTH)) {

	    char len[25], actLen[25];

	    /* FIXME, TODO: What is the max expected string length of the
	    * this value?
	    */
	    if (nodeType == XML_ATTRIBUTE_NODE)
		msg = xmlStrcat(msg, BAD_CAST "The value '%s' has a length of '%s'; ");
	    else
		msg = xmlStrcat(msg, BAD_CAST "The value has a length of '%s'; ");

	    snprintf(len, 24, "%lu", xmlSchemaGetFacetValueAsULong(facet));
	    snprintf(actLen, 24, "%lu", length);

	    if (facetType == XML_SCHEMA_FACET_LENGTH)
		msg = xmlStrcat(msg,
		BAD_CAST "this differs from the allowed length of '%s'.\n");
	    else if (facetType == XML_SCHEMA_FACET_MAXLENGTH)
		msg = xmlStrcat(msg,
		BAD_CAST "this exceeds the allowed maximum length of '%s'.\n");
	    else if (facetType == XML_SCHEMA_FACET_MINLENGTH)
		msg = xmlStrcat(msg,
		BAD_CAST "this underruns the allowed minimum length of '%s'.\n");

	    if (nodeType == XML_ATTRIBUTE_NODE)
		xmlSchemaErr3(actxt, error, node, (const char *) msg,
		    value, (const xmlChar *) actLen, (const xmlChar *) len);
	    else
		xmlSchemaErr(actxt, error, node, (const char *) msg,
		    (const xmlChar *) actLen, (const xmlChar *) len);

	} else if (facetType == XML_SCHEMA_FACET_ENUMERATION) {
	    msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not an element "
		"of the set {%s}.\n");
	    xmlSchemaErr(actxt, error, node, (const char *) msg, value,
		xmlSchemaFormatFacetEnumSet(actxt, &str, type));
	} else if (facetType == XML_SCHEMA_FACET_PATTERN) {
	    msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not accepted "
		"by the pattern '%s'.\n");
	    xmlSchemaErr(actxt, error, node, (const char *) msg, value,
		facet->value);
	} else if (facetType == XML_SCHEMA_FACET_MININCLUSIVE) {
	    msg = xmlStrcat(msg, BAD_CAST "The value '%s' is less than the "
		"minimum value allowed ('%s').\n");
	    xmlSchemaErr(actxt, error, node, (const char *) msg, value,
		facet->value);
	} else if (facetType == XML_SCHEMA_FACET_MAXINCLUSIVE) {
	    msg = xmlStrcat(msg, BAD_CAST "The value '%s' is greater than the "
		"maximum value allowed ('%s').\n");
	    xmlSchemaErr(actxt, error, node, (const char *) msg, value,
		facet->value);
	} else if (facetType == XML_SCHEMA_FACET_MINEXCLUSIVE) {
	    msg = xmlStrcat(msg, BAD_CAST "The value '%s' must be greater than "
		"'%s'.\n");
	    xmlSchemaErr(actxt, error, node, (const char *) msg, value,
		facet->value);
	} else if (facetType == XML_SCHEMA_FACET_MAXEXCLUSIVE) {
	    msg = xmlStrcat(msg, BAD_CAST "The value '%s' must be less than "
		"'%s'.\n");
	    xmlSchemaErr(actxt, error, node, (const char *) msg, value,
		facet->value);
	} else if (facetType == XML_SCHEMA_FACET_TOTALDIGITS) {
	    msg = xmlStrcat(msg, BAD_CAST "The value '%s' has more "
		"digits than are allowed ('%s').\n");
	    xmlSchemaErr(actxt, error, node, (const char*) msg, value,
		facet->value);
	} else if (facetType == XML_SCHEMA_FACET_FRACTIONDIGITS) {
	    msg = xmlStrcat(msg, BAD_CAST "The value '%s' has more fractional "
		"digits than are allowed ('%s').\n");
	    xmlSchemaErr(actxt, error, node, (const char*) msg, value,
		facet->value);
	} else if (nodeType == XML_ATTRIBUTE_NODE) {
	    msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not facet-valid.\n");
	    xmlSchemaErr(actxt, error, node, (const char *) msg, value, NULL);
	} else {
	    msg = xmlStrcat(msg, BAD_CAST "The value is not facet-valid.\n");
	    xmlSchemaErr(actxt, error, node, (const char *) msg, NULL, NULL);
	}
    } else {
	msg = xmlStrcat(msg, (const xmlChar *) message);
	msg = xmlStrcat(msg, BAD_CAST ".\n");
	xmlSchemaErr(actxt, error, node, (const char *) msg, str1, str2);
    }
    FREE_AND_NULL(str)
    xmlFree(msg);
}