mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-22 13:45:38 +00:00
Add virXMLValidateAgainstSchema helper method
Add a helper method that can validate an XML document against an RNG schema
This commit is contained in:
parent
c5b6a4a5cb
commit
6d06b0d89b
@ -304,6 +304,7 @@ typedef enum {
|
|||||||
VIR_ERR_STORAGE_VOL_EXIST = 90, /* the storage vol already exists */
|
VIR_ERR_STORAGE_VOL_EXIST = 90, /* the storage vol already exists */
|
||||||
VIR_ERR_CPU_INCOMPATIBLE = 91, /* given CPU is incompatible with host
|
VIR_ERR_CPU_INCOMPATIBLE = 91, /* given CPU is incompatible with host
|
||||||
CPU*/
|
CPU*/
|
||||||
|
VIR_ERR_XML_INVALID_SCHEMA = 92, /* XML document doens't validate against schema */
|
||||||
} virErrorNumber;
|
} virErrorNumber;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -234,11 +234,15 @@
|
|||||||
# define VIR_WARNINGS_NO_CAST_ALIGN \
|
# define VIR_WARNINGS_NO_CAST_ALIGN \
|
||||||
_Pragma ("GCC diagnostic push") \
|
_Pragma ("GCC diagnostic push") \
|
||||||
_Pragma ("GCC diagnostic ignored \"-Wcast-align\"")
|
_Pragma ("GCC diagnostic ignored \"-Wcast-align\"")
|
||||||
|
# define VIR_WARNINGS_NO_PRINTF \
|
||||||
|
_Pragma ("GCC diagnostic push") \
|
||||||
|
_Pragma ("GCC diagnostic ignored \"-Wsuggest-attribute=format\"")
|
||||||
|
|
||||||
# define VIR_WARNINGS_RESET \
|
# define VIR_WARNINGS_RESET \
|
||||||
_Pragma ("GCC diagnostic pop")
|
_Pragma ("GCC diagnostic pop")
|
||||||
# else
|
# else
|
||||||
# define VIR_WARNINGS_NO_CAST_ALIGN
|
# define VIR_WARNINGS_NO_CAST_ALIGN
|
||||||
|
# define VIR_WARNINGS_NO_PRINTF
|
||||||
# define VIR_WARNINGS_RESET
|
# define VIR_WARNINGS_RESET
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
|
@ -2252,6 +2252,7 @@ virXMLParseHelper;
|
|||||||
virXMLPickShellSafeComment;
|
virXMLPickShellSafeComment;
|
||||||
virXMLPropString;
|
virXMLPropString;
|
||||||
virXMLSaveFile;
|
virXMLSaveFile;
|
||||||
|
virXMLValidateAgainstSchema;
|
||||||
virXPathBoolean;
|
virXPathBoolean;
|
||||||
virXPathInt;
|
virXPathInt;
|
||||||
virXPathLong;
|
virXPathLong;
|
||||||
|
@ -1285,6 +1285,12 @@ virErrorMsg(virErrorNumber error, const char *info)
|
|||||||
else
|
else
|
||||||
errmsg = _("the CPU is incompatible with host CPU: %s");
|
errmsg = _("the CPU is incompatible with host CPU: %s");
|
||||||
break;
|
break;
|
||||||
|
case VIR_ERR_XML_INVALID_SCHEMA:
|
||||||
|
if (info == NULL)
|
||||||
|
errmsg = _("XML document failed to validate against schema");
|
||||||
|
else
|
||||||
|
errmsg = _("XML document failed to validate against schema: %s");
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
return errmsg;
|
return errmsg;
|
||||||
}
|
}
|
||||||
|
@ -1082,3 +1082,82 @@ virXMLInjectNamespace(xmlNodePtr node,
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void catchRNGError(void *ctx,
|
||||||
|
const char *msg,
|
||||||
|
...)
|
||||||
|
{
|
||||||
|
virBufferPtr buf = ctx;
|
||||||
|
va_list args;
|
||||||
|
|
||||||
|
va_start(args, msg);
|
||||||
|
VIR_WARNINGS_NO_PRINTF;
|
||||||
|
virBufferVasprintf(buf, msg, args);
|
||||||
|
VIR_WARNINGS_RESET;
|
||||||
|
va_end(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void ignoreRNGError(void *ctx ATTRIBUTE_UNUSED,
|
||||||
|
const char *msg ATTRIBUTE_UNUSED,
|
||||||
|
...)
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
virXMLValidateAgainstSchema(const char *schemafile,
|
||||||
|
xmlDocPtr doc)
|
||||||
|
{
|
||||||
|
xmlRelaxNGParserCtxtPtr rngParser = NULL;
|
||||||
|
xmlRelaxNGPtr rng = NULL;
|
||||||
|
xmlRelaxNGValidCtxtPtr rngValid = NULL;
|
||||||
|
virBuffer buf = VIR_BUFFER_INITIALIZER;
|
||||||
|
int ret = -1;
|
||||||
|
|
||||||
|
if (!(rngParser = xmlRelaxNGNewParserCtxt(schemafile))) {
|
||||||
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
|
_("Unable to create RNG parser for %s"),
|
||||||
|
schemafile);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
xmlRelaxNGSetParserErrors(rngParser,
|
||||||
|
catchRNGError,
|
||||||
|
ignoreRNGError,
|
||||||
|
&buf);
|
||||||
|
|
||||||
|
if (!(rng = xmlRelaxNGParse(rngParser))) {
|
||||||
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
|
_("Unable to parse RNG %s: %s"),
|
||||||
|
schemafile, virBufferCurrentContent(&buf));
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(rngValid = xmlRelaxNGNewValidCtxt(rng))) {
|
||||||
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
|
_("Unable to create RNG validation context %s"),
|
||||||
|
schemafile);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
xmlRelaxNGSetValidErrors(rngValid,
|
||||||
|
catchRNGError,
|
||||||
|
ignoreRNGError,
|
||||||
|
&buf);
|
||||||
|
|
||||||
|
if (xmlRelaxNGValidateDoc(rngValid, doc) != 0) {
|
||||||
|
virReportError(VIR_ERR_XML_INVALID_SCHEMA,
|
||||||
|
_("Unable to validate doc against %s\n%s"),
|
||||||
|
schemafile, virBufferCurrentContent(&buf));
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = 0;
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
virBufferFreeAndReset(&buf);
|
||||||
|
xmlRelaxNGFreeParserCtxt(rngParser);
|
||||||
|
xmlRelaxNGFreeValidCtxt(rngValid);
|
||||||
|
xmlRelaxNGFree(rng);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
@ -28,6 +28,7 @@
|
|||||||
# include <libxml/parser.h>
|
# include <libxml/parser.h>
|
||||||
# include <libxml/tree.h>
|
# include <libxml/tree.h>
|
||||||
# include <libxml/xpath.h>
|
# include <libxml/xpath.h>
|
||||||
|
# include <libxml/relaxng.h>
|
||||||
|
|
||||||
int virXPathBoolean(const char *xpath,
|
int virXPathBoolean(const char *xpath,
|
||||||
xmlXPathContextPtr ctxt);
|
xmlXPathContextPtr ctxt);
|
||||||
@ -176,4 +177,8 @@ int virXMLInjectNamespace(xmlNodePtr node,
|
|||||||
const char *uri,
|
const char *uri,
|
||||||
const char *key);
|
const char *key);
|
||||||
|
|
||||||
|
int
|
||||||
|
virXMLValidateAgainstSchema(const char *schemafile,
|
||||||
|
xmlDocPtr xml);
|
||||||
|
|
||||||
#endif /* __VIR_XML_H__ */
|
#endif /* __VIR_XML_H__ */
|
||||||
|
Loading…
Reference in New Issue
Block a user