2 * Copyright (C) 1995-2005, Index Data ApS
3 * See the file LICENSE for details.
5 * $Id: marcdump.c,v 1.35 2005-12-18 15:58:02 adam Exp $
8 #define _FILE_OFFSET_BITS 64
15 #include <libxml/parser.h>
16 #include <libxml/tree.h>
18 #include <libxml/xpath.h>
19 #include <libxml/xpathInternals.h>
36 #include <yaz/marcdisp.h>
37 #include <yaz/yaz-util.h>
38 #include <yaz/xmalloc.h>
39 #include <yaz/options.h>
48 static void usage(const char *prog)
50 fprintf (stderr, "Usage: %s [-c cfile] [-f from] [-t to] [-x] [-O] [-X] [-e] [-I] [-v] file...\n",
55 void print_xpath_nodes(xmlNodeSetPtr nodes, FILE* output) {
61 size = (nodes) ? nodes->nodeNr : 0;
63 fprintf(output, "Result (%d nodes):\n", size);
64 for(i = 0; i < size; ++i) {
65 assert(nodes->nodeTab[i]);
67 if(nodes->nodeTab[i]->type == XML_NAMESPACE_DECL)
71 ns = (xmlNsPtr)nodes->nodeTab[i];
72 cur = (xmlNodePtr)ns->next;
74 fprintf(output, "= namespace \"%s\"=\"%s\" for node %s:%s\n",
75 ns->prefix, ns->href, cur->ns->href, cur->name);
77 fprintf(output, "= namespace \"%s\"=\"%s\" for node %s\n",
78 ns->prefix, ns->href, cur->name);
81 else if(nodes->nodeTab[i]->type == XML_ELEMENT_NODE)
83 cur = nodes->nodeTab[i];
85 fprintf(output, "= element node \"%s:%s\"\n",
86 cur->ns->href, cur->name);
90 fprintf(output, "= element node \"%s\"\n",
96 cur = nodes->nodeTab[i];
97 fprintf(output, "= node \"%s\": type %d\n", cur->name, cur->type);
103 int main (int argc, char **argv)
106 int libxml_dom_test = 0;
107 int print_offset = 0;
116 char *from = 0, *to = 0;
118 const char *split_fname = 0;
121 setlocale(LC_CTYPE, "");
125 to = nl_langinfo(CODESET);
129 while ((r = options("pvc:xOeXIf:t:2s:", argv, argc, &arg)) != -2)
144 cfile = fopen(arg, "w");
147 xml = YAZ_MARC_SIMPLEXML;
150 xml = YAZ_MARC_OAIMARC;
153 xml = YAZ_MARC_XCHANGE;
156 xml = YAZ_MARC_MARCXML;
159 xml = YAZ_MARC_ISO2709;
171 inf = fopen(arg, "rb");
175 fprintf (stderr, "%s: cannot open %s:%s\n",
176 prog, arg, strerror (errno));
180 fprintf (cfile, "char *marc_records[] = {\n");
183 yaz_marc_t mt = yaz_marc_create();
189 cd = yaz_iconv_open(to, from);
192 fprintf(stderr, "conversion from %s to %s "
193 "unsupported\n", from, to);
196 yaz_marc_iconv(mt, cd);
198 yaz_marc_xml(mt, xml);
199 yaz_marc_debug(mt, verbose);
206 r = fread (buf, 1, 5, inf);
209 if (r && print_offset && verbose)
210 printf ("<!-- Extra %d bytes at end of file -->\n", r);
213 while (*buf < '0' || *buf > '9')
216 long off = ftell(inf) - 5;
217 if (verbose || print_offset)
218 printf("<!-- Skipping bad byte %d (0x%02X) at offset "
220 *buf & 0xff, *buf & 0xff,
222 for (i = 0; i<4; i++)
224 r = fread(buf+4, 1, 1, inf);
230 if (verbose || print_offset)
231 printf ("<!-- End of file with data -->\n");
236 long off = ftell(inf) - 5;
237 printf ("<!-- Record %d offset %ld (0x%lx) -->\n",
240 len = atoi_n(buf, 5);
241 if (len < 25 || len > 100000)
243 long off = ftell(inf) - 5;
244 printf("Bad Length %d read at offset %ld (%lx)\n",
245 len, (long) off, (long) off);
249 r = fread (buf + 5, 1, rlen, inf);
256 sprintf(fname, "%.200s%07d", split_fname, marc_no);
257 sf = fopen(fname, "wb");
260 fprintf(stderr, "Could not open %s\n", fname);
265 if (fwrite(buf, 1, len, sf) != len)
267 fprintf(stderr, "Could write content to %s\n",
274 r = yaz_marc_decode_buf (mt, buf, -1, &result, &rlen);
276 fwrite (result, rlen, 1, stdout);
278 if (r > 0 && libxml_dom_test)
280 xmlDocPtr doc = xmlParseMemory(result, rlen);
282 fprintf(stderr, "xmLParseMemory failed\n");
286 xmlXPathContextPtr xpathCtx;
287 xmlXPathObjectPtr xpathObj;
288 static const char *xpathExpr[] = {
289 "/record/datafield[@tag='245']/subfield[@code='a']",
290 "/record/datafield[@tag='100']/subfield",
291 "/record/datafield[@tag='245']/subfield[@code='a']",
292 "/record/datafield[@tag='650']/subfield",
293 "/record/datafield[@tag='650']",
296 xpathCtx = xmlXPathNewContext(doc);
298 for (i = 0; xpathExpr[i]; i++) {
299 xpathObj = xmlXPathEvalExpression(BAD_CAST xpathExpr[i], xpathCtx);
300 if(xpathObj == NULL) {
301 fprintf(stderr,"Error: unable to evaluate xpath expression \"%s\"\n", xpathExpr[i]);
305 print_xpath_nodes(xpathObj->nodesetval, stdout);
306 xmlXPathFreeObject(xpathObj);
309 xmlXPathFreeContext(xpathCtx);
319 fprintf (cfile, ",");
320 fprintf (cfile, "\n");
321 for (i = 0; i < r; i++)
324 fprintf (cfile, " \"");
325 fprintf (cfile, "\\x%02X", p[i] & 255);
327 if (i < r - 1 && (i & 15) == 15)
328 fprintf (cfile, "\"\n");
331 fprintf (cfile, "\"\n");
340 yaz_marc_destroy(mt);
343 fprintf (cfile, "};\n");
366 * indent-tabs-mode: nil
368 * vim: shiftwidth=4 tabstop=8 expandtab