From e70cbdfde382dd605d58fc112cc2458cfce37382 Mon Sep 17 00:00:00 2001 From: Adam Dickmeiss Date: Wed, 3 May 2006 13:04:46 +0000 Subject: [PATCH] Record conversion utility (yaz_record_conv_t) supports marc and XSLT conversions. --- include/yaz/nmem.h | 3 +- include/yaz/record_conv.h | 27 +++- src/nmemsdup.c | 10 +- src/record_conv.c | 362 ++++++++++++++++++++++++++++++++++++--------- test/Makefile.am | 5 +- test/tst_record_conv.c | 203 ++++++++++++++++++++++--- test/tst_record_conv.xsl | 16 ++ 7 files changed, 529 insertions(+), 97 deletions(-) create mode 100644 test/tst_record_conv.xsl diff --git a/include/yaz/nmem.h b/include/yaz/nmem.h index c0ebc9b..2f8fb6f 100644 --- a/include/yaz/nmem.h +++ b/include/yaz/nmem.h @@ -23,7 +23,7 @@ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE * OF THIS SOFTWARE. * - * $Id: nmem.h,v 1.18 2006-05-02 20:47:45 adam Exp $ + * $Id: nmem.h,v 1.19 2006-05-03 13:04:46 adam Exp $ */ /** @@ -62,6 +62,7 @@ typedef struct nmem_control *NMEM; YAZ_EXPORT void nmem_reset(NMEM n); YAZ_EXPORT int nmem_total(NMEM n); YAZ_EXPORT char *nmem_strdup (NMEM mem, const char *src); +YAZ_EXPORT char *nmem_strdup_null (NMEM mem, const char *src); YAZ_EXPORT char *nmem_strdupn (NMEM mem, const char *src, size_t n); YAZ_EXPORT void nmem_strsplit_blank(NMEM nmem, const char *dstr, char ***darray, int *num); diff --git a/include/yaz/record_conv.h b/include/yaz/record_conv.h index 1ffae60..00df235 100644 --- a/include/yaz/record_conv.h +++ b/include/yaz/record_conv.h @@ -23,7 +23,7 @@ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE * OF THIS SOFTWARE. * - * $Id: record_conv.h,v 1.1 2006-05-02 20:47:45 adam Exp $ + * $Id: record_conv.h,v 1.2 2006-05-03 13:04:46 adam Exp $ */ /** * \file record_conv.h @@ -34,6 +34,7 @@ #define YAZ_RECORD_CONV_H #include +#include #include YAZ_BEGIN_CDECL @@ -51,12 +52,13 @@ YAZ_EXPORT yaz_record_conv_t yaz_record_conv_create(void); */ YAZ_EXPORT void yaz_record_conv_destroy(yaz_record_conv_t p); - /** configures record conversion \param p record conversion handle \param node xmlNode pointer (root element of XML config) \retval 0 success \retval -1 failure + + On failure, use yaz_record_conv_get_error to get error string. \verbatim @@ -88,10 +90,23 @@ YAZ_EXPORT void yaz_record_conv_destroy(yaz_record_conv_t p); \endverbatim + */ YAZ_EXPORT int yaz_record_conv_configure(yaz_record_conv_t p, const void *node); +/** performs record conversion + \param p record conversion handle + \param input_record record to be converted (0-terminated) + \param output_record resultint record (WRBUF string) + \retval 0 success + \retval -1 failure + + On failure, use yaz_record_conv_get_error to get error string. +*/ +YAZ_EXPORT +int yaz_record_conv_record(yaz_record_conv_t p, const char *input_record, + WRBUF output_record); /** returns error string (for last error) \param p record conversion handle @@ -100,6 +115,14 @@ int yaz_record_conv_configure(yaz_record_conv_t p, const void *node); YAZ_EXPORT const char *yaz_record_conv_get_error(yaz_record_conv_t p); + +/** set path for opening stylesheets etc. + \param p record conversion handle + \param path file path (UNIX style with : / Windows with ;) +*/ +YAZ_EXPORT +void yaz_record_conv_set_path(yaz_record_conv_t p, const char *path); + YAZ_END_CDECL #endif diff --git a/src/nmemsdup.c b/src/nmemsdup.c index 2c537f6..7b2a051 100644 --- a/src/nmemsdup.c +++ b/src/nmemsdup.c @@ -2,7 +2,7 @@ * Copyright (C) 1995-2006, Index Data ApS * See the file LICENSE for details. * - * $Id: nmemsdup.c,v 1.6 2006-05-02 20:47:45 adam Exp $ + * $Id: nmemsdup.c,v 1.7 2006-05-03 13:04:46 adam Exp $ */ /** @@ -27,6 +27,14 @@ char *nmem_strdup (NMEM mem, const char *src) return dst; } +char *nmem_strdup_null(NMEM mem, const char *src) +{ + if (!src) + return 0; + else + return nmem_strdup(mem, src); +} + char *nmem_strdupn (NMEM mem, const char *src, size_t n) { char *dst = (char *)nmem_malloc (mem, n+1); diff --git a/src/record_conv.c b/src/record_conv.c index 4ceb023..e392e61 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.1 2006-05-02 20:47:45 adam Exp $ + * $Id: record_conv.c,v 1.2 2006-05-03 13:04:46 adam Exp $ */ /** * \file record_conv.c @@ -13,17 +13,21 @@ #include #endif -#if HAVE_XML2 -#include -#include -#endif - #include - +#include +#include #include #include #include #include +#include + +#if HAVE_XSLT +#include +#include +#include +#include +#include /** \brief The internal structure for yaz_record_conv_t */ struct yaz_record_conv_struct { @@ -38,14 +42,16 @@ struct yaz_record_conv_struct { /** string buffer for error messages */ WRBUF wr_error; + + /** path for opening files */ + char *path; }; /** \brief tranformation types (rule types) */ enum YAZ_RECORD_CONV_RULE { YAZ_RECORD_CONV_RULE_XSLT, - YAZ_RECORD_CONV_RULE_MARC_TO_XML, - YAZ_RECORD_CONV_RULE_XML_TO_MARC + YAZ_RECORD_CONV_RULE_MARC }; /** \brief tranformation info (rule info) */ @@ -53,23 +59,51 @@ struct yaz_record_conv_rule { enum YAZ_RECORD_CONV_RULE which; union { struct { - const char *stylesheet; + xsltStylesheetPtr xsp; + int dummy; } xslt; struct { - const char *charset; - } marc_to_xml; - struct { - const char *charset; - } xml_to_marc; + yaz_iconv_t iconv_t; + int input_format; + int output_format; + } marc; } u; struct yaz_record_conv_rule *next; }; +/** 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) + { + if (r->which == YAZ_RECORD_CONV_RULE_MARC) + { + if (r->u.marc.iconv_t) + yaz_iconv_close(r->u.marc.iconv_t); + } + else if (r->which == YAZ_RECORD_CONV_RULE_XSLT) + { + xsltFreeStylesheet(r->u.xslt.xsp); + } + } + wrbuf_rewind(p->wr_error); + nmem_reset(p->nmem); + + p->rules = 0; + + p->rules_p = &p->rules; +} + yaz_record_conv_t yaz_record_conv_create() { yaz_record_conv_t p = xmalloc(sizeof(*p)); p->nmem = nmem_create(); p->wr_error = wrbuf_alloc(); + p->rules = 0; + p->path = 0; + + yaz_record_conv_reset(p); return p; } @@ -77,13 +111,14 @@ void yaz_record_conv_destroy(yaz_record_conv_t p) { if (p) { + yaz_record_conv_reset(p); nmem_destroy(p->nmem); wrbuf_free(p->wr_error, 1); + xfree(p->path); xfree(p); } } -#if HAVE_XML2 static struct yaz_record_conv_rule *add_rule(yaz_record_conv_t p, enum YAZ_RECORD_CONV_RULE type) { @@ -95,14 +130,6 @@ static struct yaz_record_conv_rule *add_rule(yaz_record_conv_t p, return r; } -static void yaz_record_conv_reset(yaz_record_conv_t p) -{ - wrbuf_rewind(p->wr_error); - nmem_reset(p->nmem); - p->rules = 0; - p->rules_p = &p->rules; -} - static int conv_xslt(yaz_record_conv_t p, const xmlNode *ptr) { struct _xmlAttr *attr; @@ -120,70 +147,152 @@ static int conv_xslt(yaz_record_conv_t p, const xmlNode *ptr) return -1; } } - if (stylesheet) + if (!stylesheet) { - struct yaz_record_conv_rule *r = - add_rule(p, YAZ_RECORD_CONV_RULE_XSLT); - r->u.xslt.stylesheet = nmem_strdup(p->nmem, stylesheet); - return 0; + wrbuf_printf(p->wr_error, "Missing attribute 'stylesheet'"); + return -1; } - wrbuf_printf(p->wr_error, "Missing attribute 'stylesheet'"); - return -1; -} - -static int conv_marc_to_xml(yaz_record_conv_t p, const xmlNode *ptr) -{ - struct _xmlAttr *attr; - const char *charset = 0; - struct yaz_record_conv_rule *r; - - for (attr = ptr->properties; attr; attr = attr->next) + else { - if (!xmlStrcmp(attr->name, BAD_CAST "charset") && - attr->children && attr->children->type == XML_TEXT_NODE) - charset = (const char *) attr->children->content; - else + char fullpath[1024]; + xsltStylesheetPtr xsp; + if (!yaz_filepath_resolve(stylesheet, p->path, 0, fullpath)) { - wrbuf_printf(p->wr_error, "Bad attribute '%s'." - "Expected charset.", attr->name); + wrbuf_printf(p->wr_error, "could not locate '%s'. Path=%s", + stylesheet, p->path); + return -1; + } + xsp = xsltParseStylesheetFile((xmlChar*) fullpath); + if (!xsp) + { + wrbuf_printf(p->wr_error, "xsltParseStylesheetFile failed'"); return -1; } + else + { + struct yaz_record_conv_rule *r = + add_rule(p, YAZ_RECORD_CONV_RULE_XSLT); + r->u.xslt.xsp = xsp; + } } - r = add_rule(p, YAZ_RECORD_CONV_RULE_MARC_TO_XML); - if (charset) - r->u.marc_to_xml.charset = nmem_strdup(p->nmem, charset); - else - r->u.marc_to_xml.charset = 0; return 0; } -static int conv_xml_to_marc(yaz_record_conv_t p, const xmlNode *ptr) +static int conv_marc(yaz_record_conv_t p, const xmlNode *ptr) { struct _xmlAttr *attr; - const char *charset = 0; + const char *input_charset = 0; + const char *output_charset = 0; + const char *input_format = 0; + const char *output_format = 0; + int input_format_mode = 0; + int output_format_mode = 0; struct yaz_record_conv_rule *r; + yaz_iconv_t cd = 0; for (attr = ptr->properties; attr; attr = attr->next) { - if (!xmlStrcmp(attr->name, BAD_CAST "charset") && + if (!xmlStrcmp(attr->name, BAD_CAST "inputcharset") && + attr->children && attr->children->type == XML_TEXT_NODE) + input_charset = (const char *) attr->children->content; + else if (!xmlStrcmp(attr->name, BAD_CAST "outputcharset") && attr->children && attr->children->type == XML_TEXT_NODE) - charset = (const char *) attr->children->content; + output_charset = (const char *) attr->children->content; + else if (!xmlStrcmp(attr->name, BAD_CAST "inputformat") && + attr->children && attr->children->type == XML_TEXT_NODE) + input_format = (const char *) attr->children->content; + else if (!xmlStrcmp(attr->name, BAD_CAST "outputformat") && + attr->children && attr->children->type == XML_TEXT_NODE) + output_format = (const char *) attr->children->content; else { - wrbuf_printf(p->wr_error, "Bad attribute '%s'." - "Expected charset.", attr->name); + wrbuf_printf(p->wr_error, "Bad attribute '%s'.", attr->name); return -1; } } - r = add_rule(p, YAZ_RECORD_CONV_RULE_XML_TO_MARC); - if (charset) - r->u.xml_to_marc.charset = nmem_strdup(p->nmem, charset); + if (!input_format) + { + wrbuf_printf(p->wr_error, "Attribute 'inputformat' required"); + return -1; + } + else if (!strcmp(input_format, "marc")) + { + input_format_mode = YAZ_MARC_ISO2709; + } + else if (!strcmp(input_format, "xml")) + { + input_format_mode = YAZ_MARC_MARCXML; + /** Libxml2 generates UTF-8 encoding by default . + So we convert from UTF-8 to outputcharset (if defined) + */ + if (!input_charset && output_charset) + input_charset = "utf-8"; + } + else + { + wrbuf_printf(p->wr_error, "Bad inputformat: '%s'", input_format); + return -1; + } + + if (!output_format) + { + wrbuf_printf(p->wr_error, "Attribute 'outputformat' required"); + return -1; + } + else if (!strcmp(output_format, "line")) + { + output_format_mode = YAZ_MARC_LINE; + } + else if (!strcmp(output_format, "marcxml")) + { + output_format_mode = YAZ_MARC_MARCXML; + if (input_charset && !output_charset) + output_charset = "utf-8"; + } + else if (!strcmp(output_format, "marc")) + { + output_format_mode = YAZ_MARC_ISO2709; + } + else if (!strcmp(output_format, "marcxchange")) + { + output_format_mode = YAZ_MARC_XCHANGE; + if (input_charset && !output_charset) + output_charset = "utf-8"; + } else - r->u.xml_to_marc.charset = 0; + { + wrbuf_printf(p->wr_error, "Bad outputformat: '%s'", input_format); + return -1; + } + if (input_charset && output_charset) + { + cd = yaz_iconv_open(output_charset, input_charset); + if (!cd) + { + wrbuf_printf(p->wr_error, "Unsupported character set mamping" + " inputcharset=%s outputcharset=%s", + input_charset, output_charset); + return -1; + } + } + else if (input_charset) + { + wrbuf_printf(p->wr_error, "Attribute 'outputcharset' missing"); + return -1; + } + else if (output_charset) + { + wrbuf_printf(p->wr_error, "Attribute 'inputcharset' missing"); + return -1; + } + r = add_rule(p, YAZ_RECORD_CONV_RULE_MARC); + r->u.marc.iconv_t = cd; + + r->u.marc.input_format = input_format_mode; + r->u.marc.output_format = output_format_mode; return 0; } - int yaz_record_conv_configure(yaz_record_conv_t p, const void *ptr_v) { const xmlNode *ptr = ptr_v; @@ -202,20 +311,15 @@ int yaz_record_conv_configure(yaz_record_conv_t p, const void *ptr_v) if (conv_xslt(p, ptr)) return -1; } - else if (!strcmp((const char *) ptr->name, "marc_to_xml")) - { - if (conv_marc_to_xml(p, ptr)) - return -1; - } - else if (!strcmp((const char *) ptr->name, "xml_to_marc")) + else if (!strcmp((const char *) ptr->name, "marc")) { - if (conv_xml_to_marc(p, ptr)) + if (conv_marc(p, ptr)) return -1; } else { wrbuf_printf(p->wr_error, "Bad element '%s'." - "Expected xslt, marc_to_xml,...", ptr->name); + "Expected marc, xslt, ..", ptr->name); return -1; } } @@ -228,12 +332,115 @@ int yaz_record_conv_configure(yaz_record_conv_t p, const void *ptr_v) return 0; } +int yaz_record_conv_record(yaz_record_conv_t p, const char *input_record, + WRBUF output_record) +{ + int ret = 0; + WRBUF record = output_record; /* pointer transfer */ + struct yaz_record_conv_rule *r = p->rules; + wrbuf_rewind(p->wr_error); + + wrbuf_puts(record, input_record); + for (; ret == 0 && r; r = r->next) + { + if (r->which == YAZ_RECORD_CONV_RULE_XSLT) + { + xmlDocPtr doc = xmlParseMemory(wrbuf_buf(record), + wrbuf_len(record)); + if (!doc) + { + wrbuf_printf(p->wr_error, "xmlParseMemory failed"); + ret = -1; + } + else + { + xmlDocPtr res = xsltApplyStylesheet(r->u.xslt.xsp, doc, 0); + if (res) + { + xmlChar *out_buf; + int out_len; + xmlDocDumpFormatMemory (res, &out_buf, &out_len, 1); + + wrbuf_rewind(record); + wrbuf_write(record, (const char *) out_buf, out_len); + + xmlFree(out_buf); + xmlFreeDoc(res); + } + else + { + wrbuf_printf(p->wr_error, "xsltApplyStylesheet faailed"); + ret = -1; + } + xmlFreeDoc(doc); + } + } + else if (r->which == YAZ_RECORD_CONV_RULE_MARC) + { + yaz_marc_t mt = yaz_marc_create(); + + yaz_marc_xml(mt, r->u.marc.output_format); + + if (r->u.marc.iconv_t) + yaz_marc_iconv(mt, r->u.marc.iconv_t); + if (r->u.marc.input_format == YAZ_MARC_ISO2709) + { + int sz = yaz_marc_read_iso2709(mt, wrbuf_buf(record), + wrbuf_len(record)); + if (sz > 0) + ret = 0; + else + ret = -1; + } + else if (r->u.marc.input_format == YAZ_MARC_MARCXML) + { + xmlDocPtr doc = xmlParseMemory(wrbuf_buf(record), + wrbuf_len(record)); + if (!doc) + { + wrbuf_printf(p->wr_error, "xmlParseMemory failed"); + ret = -1; + } + else + { + ret = yaz_marc_read_xml(mt, xmlDocGetRootElement(doc)); + if (ret) + wrbuf_printf(p->wr_error, "yaz_marc_read_xml failed"); + } + xmlFreeDoc(doc); + } + else + { + wrbuf_printf(p->wr_error, "unsupported input format"); + ret = -1; + } + if (ret == 0) + { + wrbuf_rewind(record); + ret = yaz_marc_write_mode(mt, record); + if (ret) + wrbuf_printf(p->wr_error, "yaz_marc_write_mode failed"); + } + yaz_marc_destroy(mt); + } + } + return ret; +} + #else -/* HAVE_XML2 */ +/* !HAVE_XSLT */ int yaz_record_conv_configure(yaz_record_conv_t p, const void *ptr_v) { wrbuf_rewind(p->wr_error); - wrbuf_printf(p->wr_error, "No XML support for yaz_record_conv"); + wrbuf_printf(p->wr_error, "No XML support: yaz_record_conv_configure"); + return -1; +} + +int yaz_record_conv_record(yaz_record_conv_t p, const char *input_record, + WRBUF output_record); +{ + wrbuf_rewind(p->wr_error); + wrbuf_printf(p->wr_error, "No XML support: yaz_record_conv_record"); return -1; } @@ -244,6 +451,17 @@ const char *yaz_record_conv_get_error(yaz_record_conv_t p) return wrbuf_buf(p->wr_error); } +void yaz_record_conv_set_path(yaz_record_conv_t p, const char *path) +{ + if (p) + { + xfree(p->path); + p->path = 0; + if (path) + p->path = xstrdup(path); + } +} + /* * Local variables: * c-basic-offset: 4 diff --git a/test/Makefile.am b/test/Makefile.am index 5936e3a..55bff58 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -1,6 +1,6 @@ ## Copyright (C) 1994-2006, Index Data ApS ## All rights reserved. -## $Id: Makefile.am,v 1.16 2006-05-03 09:04:33 heikki Exp $ +## $Id: Makefile.am,v 1.17 2006-05-03 13:04:46 adam Exp $ check_PROGRAMS = tsticonv tstnmem tstmatchstr tstwrbuf tstodr tstccl tstlog \ tstsoap1 tstsoap2 tstodrstack tstlogthread tstxmlquery tstpquery nfatest1 \ @@ -16,7 +16,8 @@ EXTRA_DIST = tstodr.asn tstodrcodec.c tstodrcodec.h cqlsample \ marc3 marc3.xml marc3.chr marc3.xml.marc \ marc4 marc4.xml marc4.chr marc4.xml.marc \ marc5 marc5.xml marc5.chr marc5.xml.marc \ - marc6 marc6.xml marc6.chr marc6.xml.marc + marc6 marc6.xml marc6.chr marc6.xml.marc \ + tst_record_conv.xsl YAZCOMP = ../util/yaz-asncomp YAZCOMPLINE = $(YAZCOMP) -d z.tcl -i yaz -I../include $(YCFLAGS) diff --git a/test/tst_record_conv.c b/test/tst_record_conv.c index 66460e0..2b414c6 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.1 2006-05-02 20:47:46 adam Exp $ + * $Id: tst_record_conv.c,v 1.2 2006-05-03 13:04:46 adam Exp $ * */ #include @@ -15,7 +15,7 @@ #include #include -yaz_record_conv_t conv_from_xml(const char *xmlstring, WRBUF w) +yaz_record_conv_t conv_configure(const char *xmlstring, WRBUF w) { xmlDocPtr doc = xmlParseMemory(xmlstring, strlen(xmlstring)); if (!doc) @@ -27,7 +27,13 @@ yaz_record_conv_t conv_from_xml(const char *xmlstring, WRBUF w) { xmlNodePtr ptr = xmlDocGetRootElement(doc); yaz_record_conv_t p = yaz_record_conv_create(); - + + if (p) + { + const char *srcdir = getenv("srcdir"); + if (srcdir) + yaz_record_conv_set_path(p, srcdir); + } if (!ptr) { wrbuf_printf(w, "xmlDocGetRootElement"); @@ -54,20 +60,23 @@ yaz_record_conv_t conv_from_xml(const char *xmlstring, WRBUF w) } } -int conv_from_xml_compare(const char *xmlstring, const char *expect_error, - yaz_record_conv_t *pt) +int conv_configure_test(const char *xmlstring, const char *expect_error, + yaz_record_conv_t *pt) { WRBUF w = wrbuf_alloc(); int ret; - yaz_record_conv_t p = conv_from_xml(xmlstring, w); + yaz_record_conv_t p = conv_configure(xmlstring, w); if (!p) { if (expect_error && !strcmp(wrbuf_buf(w), expect_error)) ret = 1; else + { ret = 0; + printf("%.*s\n", wrbuf_len(w), wrbuf_buf(w)); + } } else { @@ -89,27 +98,183 @@ int conv_from_xml_compare(const char *xmlstring, const char *expect_error, return ret; } -static void tst() +static void tst_configure() +{ + 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("" + "" + "" + "", + "Attribute 'inputformat' required", 0)); + YAZ_CHECK(conv_configure_test("" + "" + "" + "", + 0, 0)); +} + +static int conv_convert_test(yaz_record_conv_t p, + const char *input_record, + const char *output_expect_record) +{ + int ret = 0; + if (!p) + { + YAZ_CHECK(ret); + } + else + { + WRBUF output_record = wrbuf_alloc(); + int r = yaz_record_conv_record(p, input_record, output_record); + if (r) + { + if (output_expect_record) + { + printf("yaz_record_conv error=%s\n", + yaz_record_conv_get_error(p)); + ret = 0; + } + else + ret = 1; + } + else + { + if (!output_expect_record) + { + ret = 0; + } + else if (strlen(output_expect_record) != wrbuf_len(output_record)) + { + int expect_len = strlen(output_expect_record); + ret = 0; + printf("output_record expect-len=%d got-len=%d\n", expect_len, + wrbuf_len(output_record)); + printf("got-output_record = %.*s\n", + wrbuf_len(output_record), wrbuf_buf(output_record)); + printf("output_expect_record = %s\n", + output_expect_record); + } + else if (memcmp(output_expect_record, wrbuf_buf(output_record), + strlen(output_expect_record))) + { + ret = 0; + printf("got-output_record = %.*s\n", + wrbuf_len(output_record), wrbuf_buf(output_record)); + printf("output_expect_record = %s\n", + output_expect_record); + } + else + { + ret = 1; + } + } + wrbuf_free(output_record, 1); + } + return ret; +} + +static void tst_convert() { - YAZ_CHECK(conv_from_xml_compare("", "Missing 'convert' element", 0)); - YAZ_CHECK(conv_from_xml_compare("", 0, 0)); - YAZ_CHECK(conv_from_xml_compare("", - "Bad element 'bad'." - "Expected xslt, marc_to_xml,...", 0)); - YAZ_CHECK(conv_from_xml_compare("" - "" - "" - "", - 0, 0)); + yaz_record_conv_t p = 0; + const char *marcxml_rec = + "\n" + " 00080nam a22000498a 4500\n" + " 11224466 \n" + " \n" + " 11224466 \n" + " \n" + "\n"; + const char *iso2709_rec = + "\x30\x30\x30\x38\x30\x6E\x61\x6D\x20\x61\x32\x32\x30\x30\x30\x34" + "\x39\x38\x61\x20\x34\x35\x30\x30\x30\x30\x31\x30\x30\x31\x33\x30" + "\x30\x30\x30\x30\x30\x31\x30\x30\x30\x31\x37\x30\x30\x30\x31\x33" + "\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("" + "" + "", + 0, &p)); + YAZ_CHECK(conv_convert_test(p, marcxml_rec, iso2709_rec)); + + YAZ_CHECK(conv_configure_test("" + "" + "", + 0, &p)); + YAZ_CHECK(conv_convert_test(p, iso2709_rec, marcxml_rec)); + + + YAZ_CHECK(conv_configure_test("" + "" + "" + "" + "" + "", + 0, &p)); + YAZ_CHECK(conv_convert_test(p, marcxml_rec, marcxml_rec)); + + + + YAZ_CHECK(conv_configure_test("" + "" + "" + "" + "" + "", + 0, &p)); + YAZ_CHECK(conv_convert_test(p, marcxml_rec, marcxml_rec)); + } + #endif int main(int argc, char **argv) { YAZ_CHECK_INIT(argc, argv); #if HAVE_XML2 - tst(); + tst_configure(); + tst_convert(); #endif YAZ_CHECK_TERM; } diff --git a/test/tst_record_conv.xsl b/test/tst_record_conv.xsl new file mode 100644 index 0000000..21d6d6b --- /dev/null +++ b/test/tst_record_conv.xsl @@ -0,0 +1,16 @@ + + + + + + + + + + + + -- 1.7.10.4