mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-22 05:35:25 +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_CPU_INCOMPATIBLE = 91, /* given CPU is incompatible with host
|
||||
CPU*/
|
||||
VIR_ERR_XML_INVALID_SCHEMA = 92, /* XML document doens't validate against schema */
|
||||
} virErrorNumber;
|
||||
|
||||
/**
|
||||
|
@ -234,11 +234,15 @@
|
||||
# define VIR_WARNINGS_NO_CAST_ALIGN \
|
||||
_Pragma ("GCC diagnostic push") \
|
||||
_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 \
|
||||
_Pragma ("GCC diagnostic pop")
|
||||
# else
|
||||
# define VIR_WARNINGS_NO_CAST_ALIGN
|
||||
# define VIR_WARNINGS_NO_PRINTF
|
||||
# define VIR_WARNINGS_RESET
|
||||
# endif
|
||||
|
||||
|
@ -2252,6 +2252,7 @@ virXMLParseHelper;
|
||||
virXMLPickShellSafeComment;
|
||||
virXMLPropString;
|
||||
virXMLSaveFile;
|
||||
virXMLValidateAgainstSchema;
|
||||
virXPathBoolean;
|
||||
virXPathInt;
|
||||
virXPathLong;
|
||||
|
@ -1285,6 +1285,12 @@ virErrorMsg(virErrorNumber error, const char *info)
|
||||
else
|
||||
errmsg = _("the CPU is incompatible with host CPU: %s");
|
||||
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;
|
||||
}
|
||||
|
@ -1082,3 +1082,82 @@ virXMLInjectNamespace(xmlNodePtr node,
|
||||
|
||||
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/tree.h>
|
||||
# include <libxml/xpath.h>
|
||||
# include <libxml/relaxng.h>
|
||||
|
||||
int virXPathBoolean(const char *xpath,
|
||||
xmlXPathContextPtr ctxt);
|
||||
@ -176,4 +177,8 @@ int virXMLInjectNamespace(xmlNodePtr node,
|
||||
const char *uri,
|
||||
const char *key);
|
||||
|
||||
int
|
||||
virXMLValidateAgainstSchema(const char *schemafile,
|
||||
xmlDocPtr xml);
|
||||
|
||||
#endif /* __VIR_XML_H__ */
|
||||
|
Loading…
Reference in New Issue
Block a user