<retrielvalinfo> config file XML syntax changed to a more intuitive and well-structur...
authorMarc Cromme <marc@indexdata.dk>
Tue, 12 Dec 2006 10:41:38 +0000 (10:41 +0000)
committerMarc Cromme <marc@indexdata.dk>
Tue, 12 Dec 2006 10:41:38 +0000 (10:41 +0000)
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 <recordinfo> YAZ record-transformation features

include/yaz/record_conv.h
src/record_conv.c
src/retrieval.c
test/tst_record_conv.c
test/tst_retrieval.c

index 4cd00e0..07f9c90 100644 (file)
@@ -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
-    <convert>
+    <backend syntax='xml'>
       <xslt stylesheet="dc2marcxml.xsl"/>
       <marc inputformat="xml" outputformat="marcxml" outputcharset="marc-8"/>
-    </convert>
+    </backend>
     \endverbatim
 
     \verbatim
-    <convert>
+    <backend syntax='usmarc' name='F'>
       <marc inputformat="marc" outputformat="marcxml" inputcharset="marc-8"/>
       <xslt stylesheet="marcxml2mods.xsl"/>
       <xslt stylesheet="mods2dc.xsl"/>
-    </convert>
+    </backend>
     \endverbatim
 
 
index 9d8a934..bf148e9 100644 (file)
@@ -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 <xslt>: "
+                     "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 <xslt stylesheet=\"%s\"/>:"
+                         " 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 <xslt stylesheet=\"%s\"/>:"
+                         " 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 <marc>: 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 <marc>: "
+                     "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 <marc inputformat='%s'>: "
+                     " 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 <marc>: 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 <marc outputformat='%s'>: "
+                     " 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 <marc inputcharset='%s' outputcharset='%s'>:"
+                         " 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 <marc>: "
+                     "attribute 'outputcharset' missing");
         return -1;
     }
     else if (output_charset)
     {
-        wrbuf_printf(p->wr_error, "Attribute 'inputcharset' missing");
+        wrbuf_printf(p->wr_error, "Element <marc>: "
+                     "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 <backend>: expected "
+                                 "<marc> or <xslt> element, got <%s>"
+                                 , ptr->name);
+                    return -1;
+                }
         }
-    }
-    else
-    {
-        wrbuf_printf(p->wr_error, "Missing 'convert' element");
-        return -1;
-    }
     return 0;
 }
 
index c9ee789..eecea4c 100644 (file)
@@ -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 <retrieval>: "
+                             " 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 <retrieval>: "
+                         " 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 <retrieval>: expected"
+                         " zero or one element <backend>, 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 <backend syntax='%s'>: "
+                                     "attribute 'syntax' has invalid "
+                                     "value '%s'", 
+                                     attr->children->content,
+                                     attr->children->content);
+                        return -1;
+                    } 
+                }
+                else {
+                    wrbuf_printf(p->wr_error, "Element <backend>: 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 <retrievalinfo>: "
+                             "expected element <retrieval>, got <%s>", 
+                             ptr->name);
                 return -1;
             }
         }
     }
     else
     {
-        wrbuf_printf(p->wr_error, "Missing 'retrievalinfo' element");
+        wrbuf_printf(p->wr_error, "Expected element <retrievalinfo>");
         return -1;
     }
     return 0;
index 89d1f72..bd1a770 100644 (file)
@@ -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 <yaz/record_conv.h>
@@ -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("<bad", "xmlParseMemory", 0));
-    YAZ_CHECK(conv_configure_test("<bad/>", "Missing 'convert' element", 0));
-    YAZ_CHECK(conv_configure_test("<convert/>", 0, 0));
-    YAZ_CHECK(conv_configure_test("<convert><bad/></convert>",
-                                  "Bad element 'bad'."
-                                  "Expected marc, xslt, ..", 0));
+
+
+    YAZ_CHECK(conv_configure_test("<backend syntax='usmarc' name='F'>"
+                                  "<bad/></backend>",
+                                  "Element <backend>: expected <marc> or "
+                                  "<xslt> element, got <bad>", 0));
+
 #if YAZ_HAVE_XSLT
-    YAZ_CHECK(conv_configure_test("<convert>"
+    YAZ_CHECK(conv_configure_test("<backend syntax='usmarc' name='F'>"
                                   "<xslt stylesheet=\"tst_record_conv.xsl\"/>"
                                   "<marc"
                                   " inputcharset=\"marc-8\""
                                   " outputcharset=\"marc-8\""
                                   "/>"
-                                  "</convert>",
-                                  "Attribute 'inputformat' required", 0));
-    YAZ_CHECK(conv_configure_test("<convert>"
+                                  "</backend>",
+                                  "Element <marc>: attribute 'inputformat' "
+                                  "required", 0));
+    YAZ_CHECK(conv_configure_test("<backend syntax='usmarc' name='F'>"
                                   "<xslt/>"
-                                  "</convert>",
-                                  "Missing attribute 'stylesheet'", 0));
-    YAZ_CHECK(conv_configure_test("<convert>"
-                                  "<xslt stylesheet=\"tst_record_conv.xsl\"/>"
+                                  "</backend>",
+                                  "Element <xslt>: attribute 'stylesheet' "
+                                  "expected", 0));
+    YAZ_CHECK(conv_configure_test("<backend syntax='usmarc' name='F'>"
                                   "<marc"
                                   " inputcharset=\"utf-8\""
                                   " outputcharset=\"marc-8\""
                                   " inputformat=\"xml\""
                                   " outputformat=\"marc\""
                                   "/>"
-                                  "</convert>",
+                                  "<xslt stylesheet=\"tst_record_conv.xsl\"/>"
+                                  "</backend>",
                                   0, 0));
 #else
-    YAZ_CHECK(conv_configure_test("<convert>"
+    YAZ_CHECK(conv_configure_test("<backend syntax='usmarc' name='F'>"
                                   "<xslt stylesheet=\"tst_record_conv.xsl\"/>"
-                                  "</convert>",
+                                  "</backend>",
                                   "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("<convert>"
+    YAZ_CHECK(conv_configure_test("<backend>"
                                   "<marc"
                                   " inputcharset=\"utf-8\""
                                   " outputcharset=\"marc-8\""
                                   " inputformat=\"xml\""
                                   " outputformat=\"marc\""
                                   "/>"
-                                  "</convert>",
+                                  "</backend>",
                                   0, &p));
     YAZ_CHECK(conv_convert_test(p, marcxml_rec, iso2709_rec));
     yaz_record_conv_destroy(p);
 
-    YAZ_CHECK(conv_configure_test("<convert>"
+    YAZ_CHECK(conv_configure_test("<backend>"
                                   "<marc"
                                   " outputcharset=\"utf-8\""
                                   " inputcharset=\"marc-8\""
                                   " outputformat=\"marcxml\""
                                   " inputformat=\"marc\""
                                   "/>"
-                                  "</convert>",
+                                  "</backend>",
                                   0, &p));
     YAZ_CHECK(conv_convert_test(p, iso2709_rec, marcxml_rec));
     yaz_record_conv_destroy(p);
 
 
-    YAZ_CHECK(conv_configure_test("<convert>"
+    YAZ_CHECK(conv_configure_test("<backend>"
                                   "<xslt stylesheet=\"tst_record_conv.xsl\"/>"
                                   "<xslt stylesheet=\"tst_record_conv.xsl\"/>"
                                   "<marc"
@@ -264,13 +270,13 @@ static void tst_convert1(void)
                                   " outputformat=\"marcxml\""
                                   " inputformat=\"marc\""
                                   "/>"
-                                  "</convert>",
+                                  "</backend>",
                                   0, &p));
     YAZ_CHECK(conv_convert_test(p, marcxml_rec, marcxml_rec));
     yaz_record_conv_destroy(p);
 
 
-    YAZ_CHECK(conv_configure_test("<convert>"
+    YAZ_CHECK(conv_configure_test("<backend>"
                                   "<xslt stylesheet=\"tst_record_conv.xsl\"/>"
                                   "<xslt stylesheet=\"tst_record_conv.xsl\"/>"
                                   "<marc"
@@ -283,7 +289,7 @@ static void tst_convert1(void)
                                   " outputformat=\"marcxml\""
                                   " inputformat=\"marc\""
                                   "/>"
-                                  "</convert>",
+                                  "</backend>",
                                   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("<convert>"
+    YAZ_CHECK(conv_configure_test("<backend>"
                                   "<marc"
                                   " inputcharset=\"utf-8\""
                                   " outputcharset=\"marc-8\""
                                   " inputformat=\"xml\""
                                   " outputformat=\"marc\""
                                   "/>"
-                                  "</convert>",
+                                  "</backend>",
                                   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
index 7a2561b..3e5cd56 100644 (file)
@@ -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 <yaz/retrieval.h>
@@ -110,57 +110,50 @@ static void tst_configure(void)
                                   "xmlParseMemory", 0));
 
     YAZ_CHECK(conv_configure_test("<bad/>", 
-                                  "Missing 'retrievalinfo' element", 0));
+                                  "Expected element <retrievalinfo>", 0));
 
     YAZ_CHECK(conv_configure_test("<retrievalinfo/>", 0, 0));
 
     YAZ_CHECK(conv_configure_test("<retrievalinfo><bad/></retrievalinfo>",
-                                  "Bad element 'bad'."
-                                  " Expected 'retrieval'", 0));
+                                  "Element <retrievalinfo>:"
+                                  " expected element <retrieval>, got <bad>",
+                                  0));
 
     YAZ_CHECK(conv_configure_test("<retrievalinfo><retrieval/>"
-                                  "</retrievalinfo>", 
+                                  "</retrievalinfo>",
                                   "Missing 'syntax' attribute", 0));
 
+
     YAZ_CHECK(conv_configure_test("<retrievalinfo>"
-                                  "<retrieval syntax=\"usmarc\">\n"
-                                  "  "
-                                  "<convert>"
-                                  "<xslt stylesheet=\"tst_record_conv.xsl\"/>"
-                                  "<marc"
-                                  " inputcharset=\"utf-8\""
-                                  " outputcharset=\"marc-8\""
-                                  " inputformat=\"xml\""
-                                  " outputformat=\"marc\""
-                                  "/>"
-                                  "</convert>"
+                                  "<retrieval" 
+                                  " unknown=\"unknown\""
+                                  ">"
                                   "</retrieval>"
                                   "</retrievalinfo>",
-                                  0, 0));
+                                  "Element <retrieval>:  expected attributes "
+                                  "'syntax', identifier' or 'name', got "
+                                  "'unknown'", 0));
 
     YAZ_CHECK(conv_configure_test("<retrievalinfo>"
-                                  "<retrieval syntax=\"usmarc\">"
-                                  "<convert>"
-                                  "<xslt stylesheet=\"tst_record_conv.xsl\"/>"
-                                  "<marc"
-                                  " inputcharset=\"utf-8\""
-                                  " outputcharset=\"marc-8\""
-                                  " inputformat=\"xml\""
-                                  " outputformat=\"marc\""
-                                  "/>"
-                                  "</convert>"
+                                  "<retrieval" 
+                                  " syntax=\"unknown_synt\""
+                                  ">"
                                   "</retrieval>"
-                                  "<retrieval syntax=\"usmarc\">"
-                                  "<convert>"
-                                  "<xslt stylesheet=\"tst_record_conv.xsl\"/>"
-                                  "<marc"
-                                  " inputcharset=\"utf-8\""
-                                  " outputcharset=\"marc-8\""
-                                  " inputformat=\"xml\""
-                                  " outputformat=\"marc\""
+                                  "</retrievalinfo>",
+                                  "Element <retrieval>:  unknown attribute "
+                                  "value syntax='unknown_synt'", 0));
+
+    YAZ_CHECK(conv_configure_test("<retrievalinfo>"
+                                  "<retrieval" 
+                                  " syntax=\"usmarc\""
                                   "/>"
-                                  "</convert>"
-                                  "</retrieval>"
+                                  "</retrievalinfo>",
+                                  0, 0));
+
+    YAZ_CHECK(conv_configure_test("<retrievalinfo>"
+                                  "<retrieval" 
+                                  " syntax=\"usmarc\""
+                                  " name=\"marcxml\"/>"
                                   "</retrievalinfo>",
                                   0, 0));
 
@@ -170,58 +163,153 @@ static void tst_configure(void)
                                   " syntax=\"usmarc\""
                                   " name=\"marcxml\"" 
                                   " identifier=\"info:srw/schema/1/marcxml-v1.1\""
-                                  ">"
-                                  "<convert/>"
-                                  "</retrieval>"
+                                  "/>"
                                   "</retrievalinfo>",
                                   0, 0));
 
+
+
     YAZ_CHECK(conv_configure_test("<retrievalinfo>"
                                   "<retrieval" 
                                   " syntax=\"usmarc\""
-                                  " name=\"marcxml\""
-                                  " backendsyntax=\"usmarc\""
-                                  " backendname=\"marcxml\""
                                   " identifier=\"info:srw/schema/1/marcxml-v1.1\""
-                                  ">"
+                                  " name=\"marcxml\">"
                                   "<convert/>"
+                                  "</retrieval>" 
+                                  "</retrievalinfo>",
+                                  "Element <retrieval>: expected zero or one element "
+                                  "<backend>, got <convert>", 0));
+
+    YAZ_CHECK(conv_configure_test("<retrievalinfo>"
+                                  "<retrieval" 
+                                  " syntax=\"usmarc\""
+                                  " identifier=\"info:srw/schema/1/marcxml-v1.1\""
+                                  " name=\"marcxml\">"
+                                  " <backend syntax=\"usmarc\""
+                                  " schema=\"marcxml\""
+                                  "/>"
                                   "</retrieval>"
                                   "</retrievalinfo>",
-                                  0, 0));
+                                  "Element <backend>: expected attributes 'syntax' or 'name,"
+                                  " got 'schema'", 0));
 
     YAZ_CHECK(conv_configure_test("<retrievalinfo>"
                                   "<retrieval" 
                                   " syntax=\"usmarc\""
+                                  " identifier=\"info:srw/schema/1/marcxml-v1.1\""
+                                  " name=\"marcxml\">"
+                                  " <backend syntax=\"usmarc\""
                                   " name=\"marcxml\""
-                                  " backendsyntax=\"usmarc\""
-                                  " backendschema=\"marcxml\""
+                                  "/>"
+                                  "</retrieval>"
+                                  "</retrievalinfo>",
+                                  0, 0));
+
+    YAZ_CHECK(conv_configure_test("<retrievalinfo>"
+                                  "<retrieval" 
+                                  " syntax=\"usmarc\""
                                   " identifier=\"info:srw/schema/1/marcxml-v1.1\""
-                                  ">"
-                                  "<convert/>"
+                                  " name=\"marcxml\">"
+                                  " <backend syntax=\"unknown\""
+                                  "/>"
                                   "</retrieval>"
                                   "</retrievalinfo>",
-                                  "Bad attribute 'backendschema'."
-                                  " Use 'backendname' instead", 
-                                  0));
+                                  "Element <backend syntax='unknown'>: "
+                                  "attribute 'syntax' has invalid value "
+                                  "'unknown'", 0));
 
 
     YAZ_CHECK(conv_configure_test("<retrievalinfo>"
                                   "<retrieval" 
-                                  " syntax=\"unknown_synt\""
-                                  ">"
-                                  "<convert/>"
+                                  " syntax=\"usmarc\""
+                                  " identifier=\"info:srw/schema/1/marcxml-v1.1\""
+                                    " name=\"marcxml\">"
+                                  " <backend syntax=\"usmarc\""
+                                  " unknown=\"silly\""
+                                  "/>"
                                   "</retrieval>"
                                   "</retrievalinfo>",
-                                  "Bad syntax 'unknown_synt'", 0));
+                                  "Element <backend>: expected attributes "
+                                  "'syntax' or 'name, got 'unknown'", 0));
+
 
     YAZ_CHECK(conv_configure_test("<retrievalinfo>"
-                                  "<retrieval" 
-                                  " backendsyntax=\"unknown_synt\""
-                                  ">"
-                                  "<convert/>"
+                                  "<retrieval syntax=\"usmarc\">"
+                                  "<backend syntax=\"xml\" name=\"dc\">"
+                                  "<xslt stylesheet=\"tst_record_conv.xsl\"/>"
+                                  "<marc"
+                                  " inputcharset=\"utf-8\""
+                                  " outputcharset=\"non-existent\""
+                                  " inputformat=\"xml\""
+                                  " outputformat=\"marc\""
+                                  "/>"
+                                  "</backend>"
                                   "</retrieval>"
                                   "</retrievalinfo>",
-                                  "Bad backendsyntax 'unknown_synt'", 0));
+                                  "Element <marc inputcharset='utf-8'"
+                                  " outputcharset='non-existent'>: Unsupported character"
+                                  " set mapping defined by attribute values", 0));
+
+    YAZ_CHECK(conv_configure_test("<retrievalinfo>"
+                                  "<retrieval syntax=\"usmarc\">"
+                                  "<backend syntax=\"xml\" name=\"dc\">"
+                                  "<xslt stylesheet=\"tst_record_conv.xsl\"/>"
+                                  "<marc"
+                                  " inputcharset=\"utf-8\""
+                                  " outputcharset=\"marc-8\""
+                                  " inputformat=\"not-existent\""
+                                  " outputformat=\"marc\""
+                                  "/>"
+                                  "</backend>"
+                                  "</retrieval>"
+                                  "</retrievalinfo>",
+                                  "Element <marc inputformat='not-existent'>:  Unsupported"
+                                  " input format defined by attribute value", 0));
+
+    YAZ_CHECK(conv_configure_test("<retrievalinfo>"
+                                  "<retrieval syntax=\"usmarc\">"
+                                  "<backend syntax=\"xml\" name=\"dc\">"
+                                  "<xslt stylesheet=\"tst_record_conv.xsl\"/>"
+                                  "<marc"
+                                  " inputcharset=\"utf-8\""
+                                  " outputcharset=\"marc-8\""
+                                  " inputformat=\"xml\""
+                                  " outputformat=\"marc\""
+                                  "/>"
+                                  "</backend>"
+                                  "</retrieval>"
+                                  "</retrievalinfo>",
+                                  0, 0));
+
+    YAZ_CHECK(conv_configure_test(
+                                  "<retrievalinfo "
+                                  " xmlns=\"http://indexdata.com/yaz\" version=\"1.0\">"
+                                  "<retrieval syntax=\"grs-1\"/>"
+                                  "<retrieval syntax=\"usmarc\" name=\"F\"/>"
+                                  "<retrieval syntax=\"usmarc\" name=\"B\"/>"
+                                  "<retrieval syntax=\"xml\" name=\"marcxml\" "
+                                  "           identifier=\"info:srw/schema/1/marcxml-v1.1\">"
+                                  "  <backend syntax=\"usmarc\" name=\"F\">"
+                                  "    <marc inputformat=\"marc\" outputformat=\"marcxml\" "
+                                  "            inputcharset=\"marc-8\"/>"
+                                  "  </backend>"
+                                  "</retrieval>"
+                                  "<retrieval syntax=\"xml\" name=\"danmarc\">"
+                                  "  <backend syntax=\"usmarc\" name=\"F\">"
+                                  "    <marc inputformat=\"marc\" outputformat=\"marcxchange\" "
+                                  "          inputcharset=\"marc-8\"/>"
+                                  "  </backend>"
+                                  "</retrieval>"
+                                  "<retrieval syntax=\"xml\" name=\"dc\" "
+                                  "           identifier=\"info:srw/schema/1/dc-v1.1\">"
+                                  "  <backend syntax=\"usmarc\" name=\"F\">"
+                                  "    <marc inputformat=\"marc\" outputformat=\"marcxml\" "
+                                  "          inputcharset=\"marc-8\"/>"
+                                  "    <xslt stylesheet=\"tst_record_conv.xsl\"/> "
+                                  "  </backend>"
+                                  "</retrieval>"
+                                  "</retrievalinfo>",
+                                  0, 0));
 
 }