1 /* This file is part of the YAZ toolkit.
2 * Copyright (C) Index Data
3 * See the file LICENSE for details.
9 #include <yaz/record_conv.h>
11 #include <yaz/wrbuf.h>
14 #include <yaz/proto.h>
15 #include <yaz/prt-ext.h>
16 #include <yaz/oid_db.h>
19 #include <libxml/parser.h>
20 #include <libxml/tree.h>
23 #include <libxslt/xslt.h>
26 yaz_record_conv_t conv_configure(const char *xmlstring, WRBUF w)
28 xmlDocPtr doc = xmlParseMemory(xmlstring, strlen(xmlstring));
31 wrbuf_printf(w, "xmlParseMemory");
36 xmlNodePtr ptr = xmlDocGetRootElement(doc);
37 yaz_record_conv_t p = yaz_record_conv_create();
41 const char *srcdir = getenv("srcdir");
43 yaz_record_conv_set_path(p, srcdir);
47 wrbuf_printf(w, "xmlDocGetRootElement");
48 yaz_record_conv_destroy(p);
53 wrbuf_printf(w, "yaz_record_conv_create");
59 int r = yaz_record_conv_configure(p, ptr);
63 wrbuf_puts(w, yaz_record_conv_get_error(p));
64 yaz_record_conv_destroy(p);
73 int conv_configure_test(const char *xmlstring, const char *expect_error,
74 yaz_record_conv_t *pt)
76 WRBUF w = wrbuf_alloc();
79 yaz_record_conv_t p = conv_configure(xmlstring, w);
83 if (expect_error && !strcmp(wrbuf_cstr(w), expect_error))
88 printf("%s\n", wrbuf_cstr(w));
103 yaz_record_conv_destroy(p);
109 static void tst_configure(void)
114 YAZ_CHECK(conv_configure_test("<bad", "xmlParseMemory", 0));
117 YAZ_CHECK(conv_configure_test("<backend syntax='usmarc' name='F'>"
119 "Element <backend>: expected <marc> or "
120 "<xslt> element, got <bad>", 0));
123 YAZ_CHECK(conv_configure_test("<backend syntax='usmarc' name='F'>"
124 "<xslt stylesheet=\"test_record_conv.xsl\"/>"
126 " inputcharset=\"marc-8\""
127 " outputcharset=\"marc-8\""
130 "Element <marc>: attribute 'inputformat' "
132 YAZ_CHECK(conv_configure_test("<backend syntax='usmarc' name='F'>"
135 "Element <xslt>: attribute 'stylesheet' "
137 YAZ_CHECK(conv_configure_test("<backend syntax='usmarc' name='F'>"
139 " inputcharset=\"utf-8\""
140 " outputcharset=\"marc-8\""
141 " inputformat=\"xml\""
142 " outputformat=\"marc\""
144 "<xslt stylesheet=\"test_record_conv.xsl\"/>"
148 YAZ_CHECK(conv_configure_test("<backend syntax='usmarc' name='F'>"
149 "<xslt stylesheet=\"test_record_conv.xsl\"/>"
152 " YAZ compiled without XSLT support", 0));
156 static int conv_convert_test(yaz_record_conv_t p,
157 const char *input_record,
158 const char *output_expect_record)
167 WRBUF output_record = wrbuf_alloc();
168 int r = yaz_record_conv_record(p, input_record, strlen(input_record),
172 if (output_expect_record)
174 printf("yaz_record_conv error=%s\n",
175 yaz_record_conv_get_error(p));
183 if (!output_expect_record)
187 else if (strcmp(output_expect_record, wrbuf_cstr(output_record)))
190 printf("got-output_record len=%ld: %s\n",
191 (long) wrbuf_len(output_record),
192 wrbuf_cstr(output_record));
193 printf("output_expect_record len=%ld %s\n",
194 (long) strlen(output_expect_record),
195 output_expect_record);
202 wrbuf_destroy(output_record);
207 static int conv_convert_test_iter(yaz_record_conv_t p,
208 const char *input_record,
209 const char *output_expect_record,
214 for (i = 0; i < num_iter; i++)
216 ret = conv_convert_test(p, input_record, output_expect_record);
223 static void tst_convert1(void)
225 yaz_record_conv_t p = 0;
226 const char *marcxml_rec =
227 "<record xmlns=\"http://www.loc.gov/MARC21/slim\">\n"
228 " <leader>00080nam a22000498a 4500</leader>\n"
229 " <controlfield tag=\"001\"> 11224466 </controlfield>\n"
230 " <datafield tag=\"010\" ind1=\" \" ind2=\" \">\n"
231 " <subfield code=\"a\"> 11224466 </subfield>\n"
234 const char *tmarcxml_rec =
235 "<r xmlns=\"http://www.indexdata.com/MARC21/turboxml\">\n"
236 " <l>00080nam a22000498a 4500</l>\n"
237 " <c001> 11224466 </c001>\n"
238 " <d010 i1=\" \" i2=\" \">\n"
239 " <sa> 11224466 </sa>\n"
242 const char *iso2709_rec =
243 "\x30\x30\x30\x38\x30\x6E\x61\x6D\x20\x61\x32\x32\x30\x30\x30\x34"
244 "\x39\x38\x61\x20\x34\x35\x30\x30\x30\x30\x31\x30\x30\x31\x33\x30"
245 "\x30\x30\x30\x30\x30\x31\x30\x30\x30\x31\x37\x30\x30\x30\x31\x33"
246 "\x1E\x20\x20\x20\x31\x31\x32\x32\x34\x34\x36\x36\x20\x1E\x20\x20"
247 "\x1F\x61\x20\x20\x20\x31\x31\x32\x32\x34\x34\x36\x36\x20\x1E\x1D";
249 const char *solrmarc_rec =
250 "\x30\x30\x30\x38\x30\x6E\x61\x6D\x20\x61\x32\x32\x30\x30\x30\x34"
251 "\x39\x38\x61\x20\x34\x35\x30\x30\x30\x30\x31\x30\x30\x31\x33\x30"
252 "\x30\x30\x30\x30\x30\x31\x30\x30\x30\x31\x37\x30\x30\x30\x31\x33"
253 "#30;\x20\x20\x20\x31\x31\x32\x32\x34\x34\x36\x36\x20#30;\x20\x20"
254 "#31;\x61\x20\x20\x20\x31\x31\x32\x32\x34\x34\x36\x36\x20#30;#29;";
256 YAZ_CHECK(conv_configure_test("<backend>"
258 " inputcharset=\"utf-8\""
259 " outputcharset=\"marc-8\""
260 " inputformat=\"xml\""
261 " outputformat=\"marc\""
265 YAZ_CHECK(conv_convert_test(p, marcxml_rec, iso2709_rec));
266 YAZ_CHECK(conv_convert_test(p, tmarcxml_rec, iso2709_rec));
267 yaz_record_conv_destroy(p);
269 YAZ_CHECK(conv_configure_test("<backend>"
271 " outputcharset=\"utf-8\""
272 " inputcharset=\"marc-8\""
273 " outputformat=\"marcxml\""
274 " inputformat=\"marc\""
278 YAZ_CHECK(conv_convert_test(p, iso2709_rec, marcxml_rec));
279 yaz_record_conv_destroy(p);
281 YAZ_CHECK(conv_configure_test("<backend>"
284 " outputcharset=\"utf-8\""
285 " inputcharset=\"marc-8\""
286 " outputformat=\"marcxml\""
287 " inputformat=\"marc\""
291 YAZ_CHECK(conv_convert_test(p, solrmarc_rec, marcxml_rec));
292 yaz_record_conv_destroy(p);
294 YAZ_CHECK(conv_configure_test("<backend>"
295 "<xslt stylesheet=\"test_record_conv.xsl\"/>"
296 "<xslt stylesheet=\"test_record_conv.xsl\"/>"
298 " inputcharset=\"utf-8\""
299 " outputcharset=\"marc-8\""
300 " inputformat=\"xml\""
301 " outputformat=\"marc\""
304 " outputcharset=\"utf-8\""
305 " inputcharset=\"marc-8\""
306 " outputformat=\"marcxml\""
307 " inputformat=\"marc\""
311 YAZ_CHECK(conv_convert_test(p, marcxml_rec, marcxml_rec));
312 yaz_record_conv_destroy(p);
315 YAZ_CHECK(conv_configure_test("<backend>"
316 "<xslt stylesheet=\"test_record_conv.xsl\"/>"
317 "<xslt stylesheet=\"test_record_conv.xsl\"/>"
319 " outputcharset=\"marc-8\""
320 " inputformat=\"xml\""
321 " outputformat=\"marc\""
324 " inputcharset=\"marc-8\""
325 " outputformat=\"marcxml\""
326 " inputformat=\"marc\""
330 YAZ_CHECK(conv_convert_test(p, marcxml_rec, marcxml_rec));
331 yaz_record_conv_destroy(p);
334 static void tst_convert2(void)
336 yaz_record_conv_t p = 0;
337 const char *marcxml_rec =
338 "<record xmlns=\"http://www.loc.gov/MARC21/slim\">\n"
339 " <leader>00080nam a22000498a 4500</leader>\n"
340 " <controlfield tag=\"001\"> 11224466 </controlfield>\n"
341 " <datafield tag=\"010\" ind1=\" \" ind2=\" \">\n"
342 " <subfield code=\"a\">københavn</subfield>\n"
345 const char *iso2709_rec =
346 "\x30\x30\x30\x37\x37\x6E\x61\x6D\x20\x61\x32\x32\x30\x30\x30\x34"
347 "\x39\x38\x61\x20\x34\x35\x30\x30\x30\x30\x31\x30\x30\x31\x33\x30"
348 "\x30\x30\x30\x30\x30\x31\x30\x30\x30\x31\x34\x30\x30\x30\x31\x33"
349 "\x1E\x20\x20\x20\x31\x31\x32\x32\x34\x34\x36\x36\x20\x1E\x20\x20"
350 "\x1F\x61\x6b\xb2\x62\x65\x6e\x68\x61\x76\x6e\x1E\x1D";
352 YAZ_CHECK(conv_configure_test("<backend>"
354 " inputcharset=\"utf-8\""
355 " outputcharset=\"marc-8\""
356 " inputformat=\"xml\""
357 " outputformat=\"marc\""
361 YAZ_CHECK(conv_convert_test_iter(p, marcxml_rec, iso2709_rec, 100));
362 yaz_record_conv_destroy(p);
365 static void tst_convert3(void)
367 NMEM nmem = nmem_create();
369 yaz_record_conv_t p = 0;
371 const char *iso2709_rec =
372 "\x30\x30\x30\x37\x37\x6E\x61\x6D\x20\x20\x32\x32\x30\x30\x30\x34"
373 "\x39\x38\x61\x20\x34\x35\x30\x30\x30\x30\x31\x30\x30\x31\x33\x30"
374 "\x30\x30\x30\x30\x30\x31\x30\x30\x30\x31\x34\x30\x30\x30\x31\x33"
375 "\x1E\x20\x20\x20\x31\x31\x32\x32\x34\x34\x36\x36\x20\x1E\x20\x20"
376 "\x1F\x61\x6b\xb2\x62\x65\x6e\x68\x61\x76\x6e\x1E\x1D";
378 const char *opacxml_rec =
380 " <bibliographicRecord>\n"
381 "<record xmlns=\"http://www.loc.gov/MARC21/slim\">\n"
382 " <leader>00077nam a22000498a 4500</leader>\n"
383 " <controlfield tag=\"001\"> 11224466 </controlfield>\n"
384 " <datafield tag=\"010\" ind1=\" \" ind2=\" \">\n"
385 " <subfield code=\"a\">k" "\xc3" "\xb8" /* oslash in UTF_8 */
386 "benhavn</subfield>\n"
389 " </bibliographicRecord>\n"
392 " <typeOfRecord>u</typeOfRecord>\n"
393 " <encodingLevel>U</encodingLevel>\n"
394 " <receiptAcqStatus>0</receiptAcqStatus>\n"
395 " <dateOfReport>000000</dateOfReport>\n"
396 " <nucCode>s-FM/GC</nucCode>\n"
397 " <localLocation>Main or Science/Business Reading Rms - STORED OFFSITE</localLocation>\n"
398 " <callNumber>MLCM 89/00602 (N)</callNumber>\n"
399 " <shelvingData>FT MEADE</shelvingData>\n"
400 " <copyNumber>Copy 1</copyNumber>\n"
403 " <enumeration>1</enumeration>\n"
404 " <chronology>2</chronology>\n"
405 " <enumAndChron>3</enumAndChron>\n"
408 " <enumeration>1</enumeration>\n"
409 " <chronology>2</chronology>\n"
410 " <enumAndChron>3</enumAndChron>\n"
415 " <availableNow value=\"1\"/>\n"
416 " <availabilityDate>20130129</availabilityDate>\n"
417 " <itemId>1226176</itemId>\n"
418 " <renewable value=\"0\"/>\n"
419 " <onHold value=\"0\"/>\n"
426 Z_OPACRecord *z_opac = nmem_malloc(nmem, sizeof(*z_opac));
427 Z_HoldingsAndCircData *h;
430 z_opac->bibliographicRecord =
431 z_ext_record_oid_nmem(nmem, yaz_oid_recsyn_usmarc,
432 iso2709_rec, strlen(iso2709_rec));
433 z_opac->num_holdingsData = 1;
434 z_opac->holdingsData = (Z_HoldingsRecord **)
435 nmem_malloc(nmem, sizeof(Z_HoldingsRecord *) * 1);
436 z_opac->holdingsData[0] = (Z_HoldingsRecord *)
437 nmem_malloc(nmem, sizeof(Z_HoldingsRecord));
438 z_opac->holdingsData[0]->which = Z_HoldingsRecord_holdingsAndCirc;
439 h = z_opac->holdingsData[0]->u.holdingsAndCirc = (Z_HoldingsAndCircData *)
440 nmem_malloc(nmem, sizeof(*h));
441 h->typeOfRecord = nmem_strdup(nmem, "u");
442 h->encodingLevel = nmem_strdup(nmem, "U");
444 h->receiptAcqStatus = nmem_strdup(nmem, "0");
445 h->generalRetention = 0;
447 h->dateOfReport = nmem_strdup(nmem, "000000");
448 h->nucCode = nmem_strdup(nmem, "s-FM/GC");
449 h->localLocation = nmem_strdup(nmem,
450 "Main or Science/Business Reading "
451 "Rms - STORED OFFSITE");
452 h->shelvingLocation = 0;
453 h->callNumber = nmem_strdup(nmem, "MLCM 89/00602 (N)");
454 h->shelvingData = nmem_strdup(nmem, "FT MEADE");
455 h->copyNumber = nmem_strdup(nmem, "Copy 1");
457 h->reproductionNote = 0;
458 h->termsUseRepro = 0;
463 h->volumes = (Z_Volume **)
464 nmem_malloc(nmem, 2 * sizeof(Z_Volume *));
466 h->volumes[0] = (Z_Volume *)
467 nmem_malloc(nmem, sizeof(Z_Volume));
468 h->volumes[1] = h->volumes[0];
470 h->volumes[0]->enumeration = nmem_strdup(nmem, "1");
471 h->volumes[0]->chronology = nmem_strdup(nmem, "2");
472 h->volumes[0]->enumAndChron = nmem_strdup(nmem, "3");
474 h->num_circulationData = 1;
475 h->circulationData = (Z_CircRecord **)
476 nmem_malloc(nmem, 1 * sizeof(Z_CircRecord *));
477 circ = h->circulationData[0] = (Z_CircRecord *)
478 nmem_malloc(nmem, sizeof(Z_CircRecord));
479 circ->availableNow = nmem_booldup(nmem, 1);
480 circ->availablityDate = nmem_strdup(nmem, "20130129");
481 circ->availableThru = 0;
482 circ->restrictions = 0;
483 circ->itemId = nmem_strdup(nmem, "1226176");
484 circ->renewable = nmem_booldup(nmem, 0);
485 circ->onHold = nmem_booldup(nmem, 0);
486 circ->enumAndChron = 0;
488 circ->temporaryLocation = 0;
490 YAZ_CHECK(conv_configure_test("<backend>"
492 " inputcharset=\"marc-8\""
493 " outputcharset=\"utf-8\""
494 " inputformat=\"marc\""
495 " outputformat=\"marcxml\""
502 WRBUF output_record = wrbuf_alloc();
503 ret = yaz_record_conv_opac_record(p, z_opac, output_record);
507 ret = strcmp(wrbuf_cstr(output_record), opacxml_rec);
511 printf("got-output_record len=%ld: %s\n",
512 (long) wrbuf_len(output_record),
513 wrbuf_cstr(output_record));
514 printf("output_expect_record len=%ld %s\n",
515 (long) strlen(opacxml_rec),
519 yaz_record_conv_destroy(p);
520 wrbuf_destroy(output_record);
523 Z_OPACRecord *opac = 0;
524 yaz_marc_t mt = yaz_marc_create();
525 ret = yaz_xml_to_opac(mt, opacxml_rec, strlen(opacxml_rec),
526 &opac, 0 /* iconv */, nmem, 0);
532 WRBUF output_record = wrbuf_alloc();
535 yaz_marc_xml(mt, YAZ_MARC_MARCXML);
536 yaz_opac_decode_wrbuf(mt, opac, output_record);
538 /* change MARC size to 00077 from 00078, due to
539 encoding of the aring (two bytes in UTF-8) */
540 p = strstr(wrbuf_buf(output_record), "00078");
545 ret = strcmp(wrbuf_cstr(output_record), opacxml_rec);
549 printf("got-output_record len=%ld: %s\n",
550 (long) wrbuf_len(output_record),
551 wrbuf_cstr(output_record));
552 printf("output_expect_record len=%ld %s\n",
553 (long) strlen(opacxml_rec),
556 wrbuf_destroy(output_record);
558 yaz_marc_destroy(mt);
565 int main(int argc, char **argv)
567 YAZ_CHECK_INIT(argc, argv);
568 yaz_log_xml_errors(0, 0 /* disable log */);
576 xsltCleanupGlobals();
587 * c-file-style: "Stroustrup"
588 * indent-tabs-mode: nil
590 * vim: shiftwidth=4 tabstop=8 expandtab