YAZ  5.34.0
marc_read_sax.c
Go to the documentation of this file.
1 /* This file is part of the YAZ toolkit.
2  * Copyright (C) Index Data
3  * See the file LICENSE for details.
4  */
5 
11 #if HAVE_CONFIG_H
12 #include <config.h>
13 #endif
14 #include <stdio.h>
15 #include <yaz/log.h>
16 #include <yaz/marc_sax.h>
17 #include <yaz/wrbuf.h>
18 #include <yaz/nmem_xml.h>
19 
20 #define MAX_IND 9
21 
22 #if YAZ_HAVE_XML2
23 
25 {
26  xmlSAXHandler saxHandler;
27  void (*cb_func)(yaz_marc_t, void *);
28  void *cb_data;
34 };
35 
36 static int get_attribute(const char *name, int nb_attributes, const xmlChar **attributes, WRBUF result)
37 {
38  int i;
39  for (i = 0; i < nb_attributes; i++)
40  {
41  if (strcmp(name, (const char *)attributes[5 * i]) == 0)
42  {
43  const char *buf = (const char *)attributes[5 * i + 3];
44  const char *end = (const char *)attributes[5 * i + 4];
45  size_t len = end - buf;
46  size_t i;
47  for (i = 0; i < len; i++) {
48  wrbuf_putc(result, buf[i]);
49  if (i < len - 4 && buf[i] == '&'
50  && buf[i+1] == '#' && buf[i+2] == '3' && buf[i+3] == '8' && buf[i+4] == ';')
51  i += 4;
52  }
53  return 1;
54  }
55  }
56  return 0;
57 }
58 
59 static void get_indicators(yaz_marc_sax_t ctx, int nb_attributes, const xmlChar **attributes)
60 {
61  char ind_cstr[5];
62  strcpy(ind_cstr, "indX");
64  int i;
65  for (i = 0; i < ctx->indicator_length; i++)
66  {
67  ind_cstr[3] = '1' + i;
68  if (!get_attribute(ind_cstr, nb_attributes, attributes, ctx->indicators))
69  wrbuf_putc(ctx->indicators, ' ');
70  }
71 }
72 
73 static void yaz_start_element_ns(void *vp,
74  const xmlChar *localname, const xmlChar *prefix,
75  const xmlChar *URI, int nb_namespaces, const xmlChar **namespaces,
76  int nb_attributes, int nb_defaulted, const xmlChar **attributes)
77 {
78  yaz_marc_sax_t ctx = vp;
79 
80  wrbuf_rewind(ctx->cdata);
81  if (strcmp((const char *)localname, "controlfield") == 0)
82  {
83  wrbuf_rewind(ctx->tag);
84  get_attribute("tag", nb_attributes, attributes, ctx->tag);
85  }
86  else if (strcmp((const char *)localname, "datafield") == 0)
87  {
88  wrbuf_rewind(ctx->tag);
89  get_attribute("tag", nb_attributes, attributes, ctx->tag);
90  get_indicators(ctx, nb_attributes, attributes);
93  }
94  else if (strcmp((const char *)localname, "subfield") == 0)
95  {
96  get_attribute("code", nb_attributes, attributes, ctx->cdata);
97  }
98  else if (strcmp((const char *)localname, "record") == 0)
99  {
100  yaz_marc_reset(ctx->mt);
101  }
102 }
103 
104 static void yaz_end_element_ns(void *vp, const xmlChar *localname,
105  const xmlChar *prefix, const xmlChar *URI)
106 {
107  yaz_marc_sax_t ctx = vp;
108  if (strcmp((const char *)localname, "leader") == 0)
109  {
110  int identifier_length;
111  int base_address;
112  int length_data_entry;
113  int length_starting;
114  int length_implementation;
116  &ctx->indicator_length, &identifier_length, &base_address,
117  &length_data_entry, &length_starting, &length_implementation);
118  }
119  else if (strcmp((const char *)localname, "controlfield") == 0)
120  {
122  wrbuf_buf(ctx->cdata), wrbuf_len(ctx->cdata));
123  }
124  else if (strcmp((const char *)localname, "subfield") == 0)
125  {
127  }
128  else if (strcmp((const char *)localname, "record") == 0)
129  {
130  ctx->cb_func(ctx->mt, ctx->cb_data);
131  }
132  wrbuf_rewind(ctx->cdata);
133 }
134 
135 static void yaz_characters(void *vp, const xmlChar *text, int len)
136 {
137  yaz_marc_sax_t ctx = vp;
138  wrbuf_write(ctx->cdata, (const char *)text, len);
139 }
140 
141 yaz_marc_sax_t yaz_marc_sax_new(yaz_marc_t mt, void (*cb)(yaz_marc_t, void *), void *cb_data)
142 {
143  yaz_marc_sax_t ctx = xmalloc(sizeof(*ctx));
144 
145  ctx->mt = mt;
146  ctx->cb_data = cb_data;
147  ctx->cb_func = cb;
148  ctx->cdata = wrbuf_alloc();
149  ctx->tag = wrbuf_alloc();
150  ctx->indicators = wrbuf_alloc();
151  memset(&ctx->saxHandler, 0, sizeof(ctx->saxHandler));
152  ctx->saxHandler.initialized = XML_SAX2_MAGIC;
153  ctx->saxHandler.startElementNs = yaz_start_element_ns;
154  ctx->saxHandler.endElementNs = yaz_end_element_ns;
155  ctx->saxHandler.characters = yaz_characters;
156  return ctx;
157 }
158 
160 {
161  return &ctx->saxHandler;
162 }
163 
165 {
167  wrbuf_destroy(ctx->cdata);
168  wrbuf_destroy(ctx->tag);
169  xfree(ctx);
170 }
171 
172 #endif
173 
174 /*
175  * Local variables:
176  * c-basic-offset: 4
177  * c-file-style: "Stroustrup"
178  * indent-tabs-mode: nil
179  * End:
180  * vim: shiftwidth=4 tabstop=8 expandtab
181  */
char * name
Definition: initopt.c:18
Logging utility.
static void yaz_start_element_ns(void *vp, const xmlChar *localname, const xmlChar *prefix, const xmlChar *URI, int nb_namespaces, const xmlChar **namespaces, int nb_attributes, int nb_defaulted, const xmlChar **attributes)
Definition: marc_read_sax.c:73
yaz_marc_sax_t yaz_marc_sax_new(yaz_marc_t mt, void(*cb)(yaz_marc_t, void *), void *cb_data)
static int get_attribute(const char *name, int nb_attributes, const xmlChar **attributes, WRBUF result)
Definition: marc_read_sax.c:36
static void get_indicators(yaz_marc_sax_t ctx, int nb_attributes, const xmlChar **attributes)
Definition: marc_read_sax.c:59
static void yaz_characters(void *vp, const xmlChar *text, int len)
static void yaz_end_element_ns(void *vp, const xmlChar *localname, const xmlChar *prefix, const xmlChar *URI)
void yaz_marc_sax_destroy(yaz_marc_sax_t ctx)
destroys marc SAX parser
xmlSAXHandlerPtr yaz_marc_sax_get_handler(yaz_marc_sax_t ctx)
return Libxml SAX handler pointer
Parsing MARCXML collection using Libxml2's SAX parser.
void yaz_marc_add_subfield(yaz_marc_t mt, const char *code_data, size_t code_data_len)
adds subfield to MARC structure
Definition: marcdisp.c:316
void yaz_marc_add_datafield(yaz_marc_t mt, const char *tag, const char *indicator, size_t indicator_len)
adds datafield to MARC structure using strings
Definition: marcdisp.c:233
void yaz_marc_set_leader(yaz_marc_t mt, const char *leader_c, int *indicator_length, int *identifier_length, int *base_address, int *length_data_entry, int *length_starting, int *length_implementation)
sets leader, validates it, and returns important values
Definition: marcdisp.c:356
void yaz_marc_add_controlfield(yaz_marc_t mt, const char *tag, const char *data, size_t data_len)
adds controlfield to MARC structure
Definition: marcdisp.c:212
void yaz_marc_reset(yaz_marc_t mt)
clears memory and MARC record
Definition: marcdisp.c:483
struct yaz_marc_t_ * yaz_marc_t
a yaz_marc_t handle (private content)
Definition: marcdisp.h:47
Header for Nibble Memory functions + Libxml2 specific stuff.
string buffer
Definition: wrbuf.h:43
xmlSAXHandler saxHandler
Definition: marc_read_sax.c:26
void(* cb_func)(yaz_marc_t, void *)
Definition: marc_read_sax.c:27
yaz_marc_t mt
Definition: marc_read_sax.c:29
the internals of a yaz_marc_t handle
Definition: marcdisp.c:86
void wrbuf_destroy(WRBUF b)
destroy WRBUF and its buffer
Definition: wrbuf.c:38
void wrbuf_rewind(WRBUF b)
empty WRBUF content (length of buffer set to 0)
Definition: wrbuf.c:47
WRBUF wrbuf_alloc(void)
construct WRBUF
Definition: wrbuf.c:25
const char * wrbuf_cstr(WRBUF b)
returns WRBUF content as C-string
Definition: wrbuf.c:281
void wrbuf_write(WRBUF b, const char *buf, size_t size)
append constant size buffer to WRBUF
Definition: wrbuf.c:68
Header for WRBUF (growing buffer)
#define wrbuf_putc(b, c)
Definition: wrbuf.h:268
#define wrbuf_buf(b)
Definition: wrbuf.h:251
#define wrbuf_len(b)
Definition: wrbuf.h:250
#define xfree(x)
utility macro which calls xfree_f
Definition: xmalloc.h:53
#define xmalloc(x)
utility macro which calls malloc_f
Definition: xmalloc.h:49