From ca44977409b92a8b1c7bfbc913a6422edc41d1d5 Mon Sep 17 00:00:00 2001 From: Marc Cromme Date: Tue, 12 Dec 2006 10:41:38 +0000 Subject: [PATCH] config file XML syntax changed to a more intuitive and well-structured format. XML parser adjusted accordingly related error messages fixed and added more context information to error messages updated test suite and added a handful more XML config file tests still missing to document the YAZ record-transformation features --- include/yaz/record_conv.h | 10 +-- src/record_conv.c | 103 +++++++++++----------- src/retrieval.c | 106 ++++++++++++++--------- test/tst_record_conv.c | 76 ++++++++-------- test/tst_retrieval.c | 210 ++++++++++++++++++++++++++++++++------------- 5 files changed, 315 insertions(+), 190 deletions(-) diff --git a/include/yaz/record_conv.h b/include/yaz/record_conv.h index 4cd00e0..07f9c90 100644 --- a/include/yaz/record_conv.h +++ b/include/yaz/record_conv.h @@ -24,7 +24,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -/* $Id: record_conv.h,v 1.5 2006-10-09 21:02:41 adam Exp $ */ +/* $Id: record_conv.h,v 1.6 2006-12-12 10:41:38 marc Exp $ */ /** * \file record_conv.h @@ -62,18 +62,18 @@ YAZ_EXPORT void yaz_record_conv_destroy(yaz_record_conv_t p); On failure, use yaz_record_conv_get_error to get error string. \verbatim - + - + \endverbatim \verbatim - + - + \endverbatim diff --git a/src/record_conv.c b/src/record_conv.c index 9d8a934..bf148e9 100644 --- a/src/record_conv.c +++ b/src/record_conv.c @@ -2,7 +2,7 @@ * Copyright (C) 2005-2006, Index Data ApS * See the file LICENSE for details. * - * $Id: record_conv.c,v 1.11 2006-07-06 10:17:53 adam Exp $ + * $Id: record_conv.c,v 1.12 2006-12-12 10:41:38 marc Exp $ */ /** * \file record_conv.c @@ -81,6 +81,7 @@ struct yaz_record_conv_rule { /** \brief reset rules+configuration */ static void yaz_record_conv_reset(yaz_record_conv_t p) { + struct yaz_record_conv_rule *r; for (r = p->rules; r; r = r->next) { @@ -164,7 +165,8 @@ static int conv_xslt(yaz_record_conv_t p, const xmlNode *ptr) } if (!stylesheet) { - wrbuf_printf(p->wr_error, "Missing attribute 'stylesheet'"); + wrbuf_printf(p->wr_error, "Element : " + "attribute 'stylesheet' expected"); return -1; } else @@ -173,14 +175,22 @@ static int conv_xslt(yaz_record_conv_t p, const xmlNode *ptr) xsltStylesheetPtr xsp; if (!yaz_filepath_resolve(stylesheet, p->path, 0, fullpath)) { - wrbuf_printf(p->wr_error, "could not locate '%s'. Path=%s", - stylesheet, p->path); + wrbuf_printf(p->wr_error, "Element :" + " could not locate stylesheet '%s' with path '%s'", + stylesheet, fullpath, p->path); return -1; } xsp = xsltParseStylesheetFile((xmlChar*) fullpath); if (!xsp) { - wrbuf_printf(p->wr_error, "xsltParseStylesheetFile failed'"); + wrbuf_printf(p->wr_error, "Element :" + " parsing stylesheet '%s' with path '%s' failed," +#if YAZ_HAVE_EXSLT + " EXSLT enabled", +#else + " EXSLT not supported", +#endif + stylesheet, fullpath, p->path); return -1; } else @@ -227,13 +237,17 @@ static int conv_marc(yaz_record_conv_t p, const xmlNode *ptr) output_format = (const char *) attr->children->content; else { - wrbuf_printf(p->wr_error, "Bad attribute '%s'", attr->name); + wrbuf_printf(p->wr_error, "Element : expected attributes" + "'inputformat', 'inputcharset', 'outputformat' or" + " 'outputcharset', got attribute '%s'", + attr->name); return -1; } } if (!input_format) { - wrbuf_printf(p->wr_error, "Attribute 'inputformat' required"); + wrbuf_printf(p->wr_error, "Element : " + "attribute 'inputformat' required"); return -1; } else if (!strcmp(input_format, "marc")) @@ -251,13 +265,17 @@ static int conv_marc(yaz_record_conv_t p, const xmlNode *ptr) } else { - wrbuf_printf(p->wr_error, "Bad inputformat: '%s'", input_format); + wrbuf_printf(p->wr_error, "Element : " + " Unsupported input format" + " defined by attribute value", + input_format); return -1; } if (!output_format) { - wrbuf_printf(p->wr_error, "Attribute 'outputformat' required"); + wrbuf_printf(p->wr_error, + "Element : attribute 'outputformat' required"); return -1; } else if (!strcmp(output_format, "line")) @@ -282,7 +300,10 @@ static int conv_marc(yaz_record_conv_t p, const xmlNode *ptr) } else { - wrbuf_printf(p->wr_error, "Bad outputformat: '%s'", input_format); + wrbuf_printf(p->wr_error, "Element : " + " Unsupported output format" + " defined by attribute value", + output_format); return -1; } if (input_charset && output_charset) @@ -290,20 +311,24 @@ static int conv_marc(yaz_record_conv_t p, const xmlNode *ptr) cd = yaz_iconv_open(output_charset, input_charset); if (!cd) { - wrbuf_printf(p->wr_error, "Unsupported character set mamping" - " inputcharset=%s outputcharset=%s", + wrbuf_printf(p->wr_error, + "Element :" + " Unsupported character set mapping" + " defined by attribute values", input_charset, output_charset); return -1; } } else if (input_charset) { - wrbuf_printf(p->wr_error, "Attribute 'outputcharset' missing"); + wrbuf_printf(p->wr_error, "Element : " + "attribute 'outputcharset' missing"); return -1; } else if (output_charset) { - wrbuf_printf(p->wr_error, "Attribute 'inputcharset' missing"); + wrbuf_printf(p->wr_error, "Element : " + "attribute 'inputcharset' missing"); return -1; } r = add_rule(p, YAZ_RECORD_CONV_RULE_MARC); @@ -320,47 +345,29 @@ int yaz_record_conv_configure(yaz_record_conv_t p, const void *ptr_v) yaz_record_conv_reset(p); - if (ptr && ptr->type == XML_ELEMENT_NODE && - !strcmp((const char *) ptr->name, "convert")) - { - for (ptr = ptr->children; ptr; ptr = ptr->next) + /* parsing element children */ + for (ptr = ptr->children; ptr; ptr = ptr->next) { if (ptr->type != XML_ELEMENT_NODE) continue; if (!strcmp((const char *) ptr->name, "xslt")) - { - if (conv_xslt(p, ptr)) - return -1; - } - else if (!strcmp((const char *) ptr->name, "exslt")) - { -#if YAZ_HAVE_EXSLT - if (conv_xslt(p, ptr)) - return -1; -#else - wrbuf_printf(p->wr_error, "exslt unsupported." - " YAZ compiled without EXSLT support"); - return -1; -#endif - } + { + if (conv_xslt(p, ptr)) + return -1; + } else if (!strcmp((const char *) ptr->name, "marc")) - { - if (conv_marc(p, ptr)) - return -1; - } + { + if (conv_marc(p, ptr)) + return -1; + } else - { - wrbuf_printf(p->wr_error, "Bad element '%s'." - "Expected marc, xslt, ..", ptr->name); - return -1; - } + { + wrbuf_printf(p->wr_error, "Element : expected " + " or element, got <%s>" + , ptr->name); + return -1; + } } - } - else - { - wrbuf_printf(p->wr_error, "Missing 'convert' element"); - return -1; - } return 0; } diff --git a/src/retrieval.c b/src/retrieval.c index c9ee789..eecea4c 100644 --- a/src/retrieval.c +++ b/src/retrieval.c @@ -2,7 +2,7 @@ * Copyright (C) 2005-2006, Index Data ApS * See the file LICENSE for details. * - * $Id: retrieval.c,v 1.12 2006-10-10 09:13:52 adam Exp $ + * $Id: retrieval.c,v 1.13 2006-12-12 10:41:38 marc Exp $ */ /** * \file retrieval.c @@ -51,10 +51,11 @@ struct yaz_retrieval_struct { struct yaz_retrieval_elem { /** \brief schema identifier */ const char *identifier; - /** \brief schema name , short-hand such sa "dc" */ + /** \brief schema name , short-hand such as "dc" */ const char *name; /** \brief record syntax */ int *syntax; + /** \brief backend name */ const char *backend_name; /** \brief backend syntax */ @@ -131,7 +132,8 @@ static int conf_retrieval(yaz_retrieval_t p, const xmlNode *ptr) (const char *) attr->children->content); if (!el->syntax) { - wrbuf_printf(p->wr_error, "Bad syntax '%s'", + wrbuf_printf(p->wr_error, "Element : " + " unknown attribute value syntax='%s'", (const char *) attr->children->content); return -1; } @@ -140,61 +142,82 @@ static int conf_retrieval(yaz_retrieval_t p, const xmlNode *ptr) attr->children && attr->children->type == XML_TEXT_NODE) el->identifier = nmem_strdup(p->nmem, (const char *) attr->children->content); - else if (!xmlStrcmp(attr->name, BAD_CAST "schema") && - attr->children && attr->children->type == XML_TEXT_NODE) - { - wrbuf_printf(p->wr_error, "Bad attribute 'schema'. " - "Use 'name' instead"); - return -1; - } else if (!xmlStrcmp(attr->name, BAD_CAST "name") && attr->children && attr->children->type == XML_TEXT_NODE) el->name = nmem_strdup(p->nmem, (const char *) attr->children->content); - else if (!xmlStrcmp(attr->name, BAD_CAST "backendschema") && - attr->children && attr->children->type == XML_TEXT_NODE) - { - wrbuf_printf(p->wr_error, "Bad attribute 'backendschema'. " - "Use 'backendname' instead"); - return -1; - } - else if (!xmlStrcmp(attr->name, BAD_CAST "backendname") && - attr->children && attr->children->type == XML_TEXT_NODE) - el->backend_name = - nmem_strdup(p->nmem, (const char *) attr->children->content); - else if (!xmlStrcmp(attr->name, BAD_CAST "backendsyntax") && - attr->children && attr->children->type == XML_TEXT_NODE) - { - el->backend_syntax = yaz_str_to_z3950oid( - p->odr, CLASS_RECSYN, - (const char *) attr->children->content); - if (!el->backend_syntax) - { - wrbuf_printf(p->wr_error, "Bad backendsyntax '%s'", - (const char *) attr->children->content); - return -1; - } - } else { - wrbuf_printf(p->wr_error, "Bad attribute '%s'.", attr->name); + wrbuf_printf(p->wr_error, "Element : " + " expected attributes 'syntax', identifier' or " + "'name', got '%s'", attr->name); return -1; } } + if (!el->syntax) { wrbuf_printf(p->wr_error, "Missing 'syntax' attribute"); return -1; } - el->record_conv = 0; /* OK to have no 'convert' sub content */ + /* parsing backend element */ + + el->record_conv = 0; /* OK to have no 'backend' sub content */ for (ptr = ptr->children; ptr; ptr = ptr->next) { - if (ptr->type == XML_ELEMENT_NODE) - { + if (ptr->type == XML_ELEMENT_NODE + && 0 != strcmp((const char *) ptr->name, "backend")){ + wrbuf_printf(p->wr_error, "Element : expected" + " zero or one element , got <%s>", + (const char *) ptr->name); + return -1; + } + + else { + + /* parsing attributees */ + struct _xmlAttr *attr; + for (attr = ptr->properties; attr; attr = attr->next){ + + if (!xmlStrcmp(attr->name, BAD_CAST "name") + && attr->children + && attr->children->type == XML_TEXT_NODE) + el->backend_name + = nmem_strdup(p->nmem, + (const char *) attr->children->content); + + else if (!xmlStrcmp(attr->name, BAD_CAST "syntax") + && attr->children + && attr->children->type == XML_TEXT_NODE){ + el->backend_syntax + = yaz_str_to_z3950oid(p->odr, CLASS_RECSYN, + (const char *) attr->children->content); + + if (!el->backend_syntax){ + wrbuf_printf(p->wr_error, + "Element : " + "attribute 'syntax' has invalid " + "value '%s'", + attr->children->content, + attr->children->content); + return -1; + } + } + else { + wrbuf_printf(p->wr_error, "Element : expected " + "attributes 'syntax' or 'name, got '%s'", + attr->name); + return -1; + } + } + + + /* parsing internal of record conv */ el->record_conv = yaz_record_conv_create(); yaz_record_conv_set_path(el->record_conv, p->path); + if (yaz_record_conv_configure(el->record_conv, ptr)) { @@ -231,15 +254,16 @@ int yaz_retrieval_configure(yaz_retrieval_t p, const void *ptr_v) } else { - wrbuf_printf(p->wr_error, "Bad element '%s'." - " Expected 'retrieval'", ptr->name); + wrbuf_printf(p->wr_error, "Element : " + "expected element , got <%s>", + ptr->name); return -1; } } } else { - wrbuf_printf(p->wr_error, "Missing 'retrievalinfo' element"); + wrbuf_printf(p->wr_error, "Expected element "); return -1; } return 0; diff --git a/test/tst_record_conv.c b/test/tst_record_conv.c index 89d1f72..bd1a770 100644 --- a/test/tst_record_conv.c +++ b/test/tst_record_conv.c @@ -2,7 +2,7 @@ * Copyright (C) 2005-2006, Index Data ApS * See the file LICENSE for details. * - * $Id: tst_record_conv.c,v 1.11 2006-10-04 16:59:34 mike Exp $ + * $Id: tst_record_conv.c,v 1.12 2006-12-12 10:41:39 marc Exp $ * */ #include @@ -52,6 +52,8 @@ yaz_record_conv_t conv_configure(const char *xmlstring, WRBUF w) } else { + + int r = yaz_record_conv_configure(p, ptr); if (r) @@ -87,19 +89,16 @@ int conv_configure_test(const char *xmlstring, const char *expect_error, else { if (expect_error) - { ret = 0; - yaz_record_conv_destroy(p); - } else - { ret = 1; - } } + if (pt) *pt = p; else - yaz_record_conv_destroy(p); + if (p) + yaz_record_conv_destroy(p); wrbuf_free(w, 1); return ret; @@ -107,42 +106,49 @@ int conv_configure_test(const char *xmlstring, const char *expect_error, static void tst_configure(void) { + + + YAZ_CHECK(conv_configure_test("", "Missing 'convert' element", 0)); - YAZ_CHECK(conv_configure_test("", 0, 0)); - YAZ_CHECK(conv_configure_test("", - "Bad element 'bad'." - "Expected marc, xslt, ..", 0)); + + + YAZ_CHECK(conv_configure_test("" + "", + "Element : expected or " + " element, got ", 0)); + #if YAZ_HAVE_XSLT - YAZ_CHECK(conv_configure_test("" + YAZ_CHECK(conv_configure_test("" "" "" - "", - "Attribute 'inputformat' required", 0)); - YAZ_CHECK(conv_configure_test("" + "", + "Element : attribute 'inputformat' " + "required", 0)); + YAZ_CHECK(conv_configure_test("" "" - "", - "Missing attribute 'stylesheet'", 0)); - YAZ_CHECK(conv_configure_test("" - "" + "", + "Element : attribute 'stylesheet' " + "expected", 0)); + YAZ_CHECK(conv_configure_test("" "" - "", + "" + "", 0, 0)); #else - YAZ_CHECK(conv_configure_test("" + YAZ_CHECK(conv_configure_test("" "" - "", + "", "xslt unsupported." " YAZ compiled without XSLT support", 0)); -#endif +#endif } static int conv_convert_test(yaz_record_conv_t p, @@ -224,32 +230,32 @@ static void tst_convert1(void) "\x1E\x20\x20\x20\x31\x31\x32\x32\x34\x34\x36\x36\x20\x1E\x20\x20" "\x1F\x61\x20\x20\x20\x31\x31\x32\x32\x34\x34\x36\x36\x20\x1E\x1D"; - YAZ_CHECK(conv_configure_test("" + YAZ_CHECK(conv_configure_test("" "" - "", + "", 0, &p)); YAZ_CHECK(conv_convert_test(p, marcxml_rec, iso2709_rec)); yaz_record_conv_destroy(p); - YAZ_CHECK(conv_configure_test("" + YAZ_CHECK(conv_configure_test("" "" - "", + "", 0, &p)); YAZ_CHECK(conv_convert_test(p, iso2709_rec, marcxml_rec)); yaz_record_conv_destroy(p); - YAZ_CHECK(conv_configure_test("" + YAZ_CHECK(conv_configure_test("" "" "" "" - "", + "", 0, &p)); YAZ_CHECK(conv_convert_test(p, marcxml_rec, marcxml_rec)); yaz_record_conv_destroy(p); - YAZ_CHECK(conv_configure_test("" + YAZ_CHECK(conv_configure_test("" "" "" "" - "", + "", 0, &p)); YAZ_CHECK(conv_convert_test(p, marcxml_rec, marcxml_rec)); yaz_record_conv_destroy(p); @@ -307,14 +313,14 @@ static void tst_convert2(void) "\x1E\x20\x20\x20\x31\x31\x32\x32\x34\x34\x36\x36\x20\x1E\x20\x20" "\x1F\x61\x6b\xb2\x62\x65\x6e\x68\x61\x76\x6e\x1E\x1D"; - YAZ_CHECK(conv_configure_test("" + YAZ_CHECK(conv_configure_test("" "" - "", + "", 0, &p)); YAZ_CHECK(conv_convert_test(p, marcxml_rec, iso2709_rec)); yaz_record_conv_destroy(p); @@ -329,7 +335,7 @@ int main(int argc, char **argv) #if YAZ_HAVE_XML2 tst_configure(); #endif -#if YAZ_HAVE_XSLT +#if YAZ_HAVE_XSLT tst_convert1(); tst_convert2(); #endif diff --git a/test/tst_retrieval.c b/test/tst_retrieval.c index 7a2561b..3e5cd56 100644 --- a/test/tst_retrieval.c +++ b/test/tst_retrieval.c @@ -2,7 +2,7 @@ * Copyright (C) 2005-2006, Index Data ApS * See the file LICENSE for details. * - * $Id: tst_retrieval.c,v 1.7 2006-10-04 16:59:34 mike Exp $ + * $Id: tst_retrieval.c,v 1.8 2006-12-12 10:41:39 marc Exp $ * */ #include @@ -110,57 +110,50 @@ static void tst_configure(void) "xmlParseMemory", 0)); YAZ_CHECK(conv_configure_test("", - "Missing 'retrievalinfo' element", 0)); + "Expected element ", 0)); YAZ_CHECK(conv_configure_test("", 0, 0)); YAZ_CHECK(conv_configure_test("", - "Bad element 'bad'." - " Expected 'retrieval'", 0)); + "Element :" + " expected element , got ", + 0)); YAZ_CHECK(conv_configure_test("" - "", + "", "Missing 'syntax' attribute", 0)); + YAZ_CHECK(conv_configure_test("" - "\n" - " " - "" - "" - "" - "" + "" "" "", - 0, 0)); + "Element : expected attributes " + "'syntax', identifier' or 'name', got " + "'unknown'", 0)); YAZ_CHECK(conv_configure_test("" - "" - "" - "" - "" - "" + "" "" - "" - "" - "" - "", + "Element : unknown attribute " + "value syntax='unknown_synt'", 0)); + + YAZ_CHECK(conv_configure_test("" + "" - "" - "" + "", + 0, 0)); + + YAZ_CHECK(conv_configure_test("" + "" "", 0, 0)); @@ -170,58 +163,153 @@ static void tst_configure(void) " syntax=\"usmarc\"" " name=\"marcxml\"" " identifier=\"info:srw/schema/1/marcxml-v1.1\"" - ">" - "" - "" + "/>" "", 0, 0)); + + YAZ_CHECK(conv_configure_test("" "" + " name=\"marcxml\">" "" + "" + "", + "Element : expected zero or one element " + ", got ", 0)); + + YAZ_CHECK(conv_configure_test("" + "" + " " "" "", - 0, 0)); + "Element : expected attributes 'syntax' or 'name," + " got 'schema'", 0)); YAZ_CHECK(conv_configure_test("" "" + " " + "" + "", + 0, 0)); + + YAZ_CHECK(conv_configure_test("" + "" - "" + " name=\"marcxml\">" + " " "" "", - "Bad attribute 'backendschema'." - " Use 'backendname' instead", - 0)); + "Element : " + "attribute 'syntax' has invalid value " + "'unknown'", 0)); YAZ_CHECK(conv_configure_test("" "" - "" + " syntax=\"usmarc\"" + " identifier=\"info:srw/schema/1/marcxml-v1.1\"" + " name=\"marcxml\">" + " " "" "", - "Bad syntax 'unknown_synt'", 0)); + "Element : expected attributes " + "'syntax' or 'name, got 'unknown'", 0)); + YAZ_CHECK(conv_configure_test("" - "" - "" + "" + "" + "" + "" + "" "" "", - "Bad backendsyntax 'unknown_synt'", 0)); + "Element : Unsupported character" + " set mapping defined by attribute values", 0)); + + YAZ_CHECK(conv_configure_test("" + "" + "" + "" + "" + "" + "" + "", + "Element : Unsupported" + " input format defined by attribute value", 0)); + + YAZ_CHECK(conv_configure_test("" + "" + "" + "" + "" + "" + "" + "", + 0, 0)); + + YAZ_CHECK(conv_configure_test( + "" + "" + "" + "" + "" + " " + " " + " " + "" + "" + " " + " " + " " + "" + "" + " " + " " + " " + " " + "" + "", + 0, 0)); } -- 1.7.10.4