[libxml2] Add value-of tag support
- From: Nick Wellnhofer <nwellnhof src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libxml2] Add value-of tag support
- Date: Wed, 2 Mar 2022 13:56:25 +0000 (UTC)
commit 2cc93f77543b5721257f795f303bfb56a4b384c7
Author: Oliver Diehl <oliver diehl nxp com>
Date: Tue Jan 11 14:43:44 2022 +0100
Add value-of tag support
schematron.c | 107 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 105 insertions(+), 2 deletions(-)
---
diff --git a/schematron.c b/schematron.c
index 2d2e03ec..331f683c 100644
--- a/schematron.c
+++ b/schematron.c
@@ -33,6 +33,7 @@
#include <libxml/xpathInternals.h>
#include <libxml/pattern.h>
#include <libxml/schematron.h>
+#include <libxml/debugXML.h>
#define SCHEMATRON_PARSE_OPTIONS XML_PARSE_NOENT
@@ -838,6 +839,57 @@ xmlSchematronAddNamespace(xmlSchematronParserCtxtPtr ctxt,
}
+/**
+ * xmlSchematronParseTestReportMsg:
+ * @ctxt: the schema parser context
+ * @con: the assert or report node
+ *
+ * Format the message content of the assert or report test
+ */
+static void
+xmlSchematronParseTestReportMsg(xmlSchematronParserCtxtPtr ctxt, xmlNodePtr con)
+{
+ xmlNodePtr child;
+ xmlXPathCompExprPtr comp;
+
+ child = con->children;
+ while (child != NULL) {
+ if ((child->type == XML_TEXT_NODE) ||
+ (child->type == XML_CDATA_SECTION_NODE))
+ /* Do Nothing */
+ {}
+ else if (IS_SCHEMATRON(child, "name")) {
+ /* Do Nothing */
+ } else if (IS_SCHEMATRON(child, "value-of")) {
+ xmlChar *select;
+
+ select = xmlGetNoNsProp(child, BAD_CAST "select");
+
+ if (select == NULL) {
+ xmlSchematronPErr(ctxt, child,
+ XML_SCHEMAV_ATTRINVALID,
+ "value-of has no select attribute",
+ NULL, NULL);
+ } else {
+ /*
+ * try first to compile the test expression
+ */
+ comp = xmlXPathCtxtCompile(ctxt->xctxt, select);
+ if (comp == NULL) {
+ xmlSchematronPErr(ctxt, child,
+ XML_SCHEMAV_ATTRINVALID,
+ "Failed to compile select expression %s",
+ select, NULL);
+ }
+ xmlXPathFreeCompExpr(comp);
+ }
+ xmlFree(select);
+ }
+ child = child->next;
+ continue;
+ }
+}
+
/**
* xmlSchematronParseRule:
* @ctxt: a schema validation context
@@ -901,7 +953,7 @@ xmlSchematronParseRule(xmlSchematronParserCtxtPtr ctxt,
NULL, NULL);
xmlFree(test);
} else {
- /* TODO will need dynamic processing instead */
+ xmlSchematronParseTestReportMsg(ctxt, cur);
report = xmlNodeGetContent(cur);
testptr = xmlSchematronAddTest(ctxt, XML_SCHEMATRON_ASSERT,
@@ -924,7 +976,7 @@ xmlSchematronParseRule(xmlSchematronParserCtxtPtr ctxt,
NULL, NULL);
xmlFree(test);
} else {
- /* TODO will need dynamic processing instead */
+ xmlSchematronParseTestReportMsg(ctxt, cur);
report = xmlNodeGetContent(cur);
testptr = xmlSchematronAddTest(ctxt, XML_SCHEMATRON_REPORT,
@@ -1294,6 +1346,7 @@ xmlSchematronFormatReport(xmlSchematronValidCtxtPtr ctxt,
xmlNodePtr test, xmlNodePtr cur) {
xmlChar *ret = NULL;
xmlNodePtr child, node;
+ xmlXPathCompExprPtr comp;
if ((test == NULL) || (cur == NULL))
return(ret);
@@ -1323,6 +1376,56 @@ xmlSchematronFormatReport(xmlSchematronValidCtxtPtr ctxt,
ret = xmlStrcat(ret, BAD_CAST ":");
ret = xmlStrcat(ret, node->name);
}
+ } else if (IS_SCHEMATRON(child, "value-of")) {
+ xmlChar *select;
+ xmlXPathObjectPtr eval;
+
+ select = xmlGetNoNsProp(child, BAD_CAST "select");
+ comp = xmlXPathCtxtCompile(ctxt->xctxt, select);
+ eval = xmlXPathCompiledEval(comp, ctxt->xctxt);
+
+ switch (eval->type) {
+ case XPATH_NODESET: {
+ int indx;
+ xmlChar *spacer = BAD_CAST " ";
+
+ if (eval->nodesetval) {
+ for (indx = 0; indx < eval->nodesetval->nodeNr; indx++) {
+ if (indx > 0)
+ ret = xmlStrcat(ret, spacer);
+ ret = xmlStrcat(ret, eval->nodesetval->nodeTab[indx]->name);
+ }
+ } else {
+ xmlGenericError(xmlGenericErrorContext,
+ "Empty node set\n");
+ }
+ break;
+ }
+ case XPATH_BOOLEAN:
+ ret = xmlStrcat(ret, BAD_CAST xmlBoolToText(eval->boolval));
+ break;
+ case XPATH_NUMBER: {
+ xmlChar *buf;
+ int size;
+
+ size = snprintf(NULL, 0, "%0g", eval->floatval);
+ buf = (xmlChar*) malloc(size * sizeof(xmlChar));
+ /* xmlStrPrintf(buf, size, "%0g", eval->floatval); // doesn't work */
+ sprintf((char*) buf, "%0g", eval->floatval);
+ ret = xmlStrcat(ret, buf);
+ free(buf);
+ break;
+ }
+ case XPATH_STRING:
+ ret = xmlStrcat(ret, eval->stringval);
+ break;
+ default:
+ xmlGenericError(xmlGenericErrorContext,
+ "Unsupported XPATH Type: %d\n", eval->type);
+ }
+ xmlXPathFreeObject(eval);
+ xmlXPathFreeCompExpr(comp);
+ xmlFree(select);
} else {
child = child->next;
continue;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]