YAZ 5.35.1
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
35
36static 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
59static 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
73static 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
104static 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
135static 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
141yaz_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)
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)
static void get_indicators(yaz_marc_sax_t ctx, int nb_attributes, const xmlChar **attributes)
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
void(* cb_func)(yaz_marc_t, void *)
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
const char * wrbuf_cstr(WRBUF b)
returns WRBUF content as C-string
Definition wrbuf.c:299
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
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:287
#define wrbuf_buf(b)
Definition wrbuf.h:270
#define wrbuf_len(b)
Definition wrbuf.h:269
#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