YAZ 5.35.1
xml_to_opac.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 */
9#if HAVE_CONFIG_H
10#include <config.h>
11#endif
12
13#include <stdio.h>
14#include <string.h>
15#include <stdlib.h>
16
17#include <yaz/proto.h>
18#include <yaz/marcdisp.h>
19#include <yaz/wrbuf.h>
20#include <yaz/oid_db.h>
21
22#if YAZ_HAVE_XML2
23#include "sru-p.h"
24
25static int match_element_next(xmlNode **ptr, const char *elem, NMEM nmem,
26 char **val)
27{
28 while (*ptr && (*ptr)->type != XML_ELEMENT_NODE)
29 (*ptr) = (*ptr)->next;
30 if (yaz_match_xsd_string_n_nmem(*ptr, elem, nmem, val, 0))
31 {
32 *ptr = (*ptr)->next;
33 return 1;
34 }
35 *val = 0;
36 return 0;
37}
38
39static int match_v_next(xmlNode **ptr, const char *elem, NMEM nmem,
40 Odr_bool **val)
41{
42 while (*ptr && (*ptr)->type != XML_ELEMENT_NODE)
43 (*ptr) = (*ptr)->next;
44 *val = nmem_booldup(nmem, 0);
45 if (yaz_match_xsd_element(*ptr, elem))
46 {
47 struct _xmlAttr *attr = (*ptr)->properties;
48
49 *ptr = (*ptr)->next;
50 for (; attr; attr = attr->next)
51 {
52 if (!strcmp((const char *) attr->name, "value"))
53 {
54 if (attr->children->type == XML_TEXT_NODE)
55 {
56 if (attr->children->content[0] == '0')
57 return 1;
58 else if (attr->children->content[0] == '1')
59 {
60 **val = 1;
61 return 1;
62 }
63 }
64 }
65 }
66 }
67 return 0;
68}
69
70static int bibliographicRecord(yaz_marc_t mt, xmlNode *ptr, Z_External **ext,
71 NMEM nmem, const Odr_oid *syntax)
72{
73 int ret = 0;
74 if (yaz_marc_read_xml(mt, ptr) == 0)
75 {
76 WRBUF wr = wrbuf_alloc();
77 if (yaz_marc_write_iso2709(mt, wr) == 0)
78 {
80 nmem, syntax ? syntax : yaz_oid_recsyn_usmarc,
81 wrbuf_buf(wr), wrbuf_len(wr));
82 ret = 1;
83 }
84 wrbuf_destroy(wr);
85 }
86 return ret;
87}
88
89static int volume(xmlNode *ptr, Z_Volume **volp, NMEM nmem)
90{
91 *volp = (Z_Volume *) nmem_malloc(nmem, sizeof(Z_Volume));
92
93 match_element_next(&ptr, "enumeration", nmem, &(*volp)->enumeration);
94 match_element_next(&ptr, "chronology", nmem, &(*volp)->chronology);
95 match_element_next(&ptr, "enumAndChron", nmem, &(*volp)->enumAndChron);
96 return 1;
97}
98
99static int volumes(xmlNode *ptr, Z_Volume ***volp, int *num, NMEM nmem)
100{
101 int i;
102 xmlNode *ptr0 = ptr;
103
104 for (i = 0; ptr; i++)
105 {
106 while (ptr && ptr->type != XML_ELEMENT_NODE)
107 ptr = ptr->next;
108 if (!ptr)
109 break;
110 if (!yaz_match_xsd_element(ptr, "volume"))
111 return 0;
112 ptr = ptr->next;
113 }
114 *num = i;
115 *volp = (Z_Volume **) nmem_malloc(nmem, sizeof(**volp) * i);
116 ptr = ptr0;
117 for (i = 0; ptr; i++)
118 {
119 while (ptr && ptr->type != XML_ELEMENT_NODE)
120 ptr = ptr->next;
121 if (!ptr)
122 break;
123 if (!yaz_match_xsd_element(ptr, "volume"))
124 return 0;
125 volume(ptr->children, (*volp) + i, nmem);
126 ptr = ptr->next;
127 }
128 return 1;
129}
130
131static int circulation(xmlNode *ptr, Z_CircRecord **circp, NMEM nmem)
132{
133 *circp = (Z_CircRecord *) nmem_malloc(nmem, sizeof(Z_CircRecord));
134
135 match_v_next(&ptr, "availableNow", nmem, &(*circp)->availableNow);
136 /* note the spelling of the ASN.1 member below */
137 match_element_next(&ptr, "availabilityDate", nmem,
138 &(*circp)->availablityDate);
139 match_element_next(&ptr, "availableThru", nmem, &(*circp)->availableThru);
140 match_element_next(&ptr, "restrictions", nmem, &(*circp)->restrictions);
141 match_element_next(&ptr, "itemId", nmem, &(*circp)->itemId);
142 match_v_next(&ptr, "renewable", nmem, &(*circp)->renewable);
143 match_v_next(&ptr, "onHold", nmem, &(*circp)->onHold);
144 match_element_next(&ptr, "enumAndChron", nmem, &(*circp)->enumAndChron);
145 match_element_next(&ptr, "midspine", nmem, &(*circp)->midspine);
146 match_element_next(&ptr, "temporaryLocation", nmem,
147 &(*circp)->temporaryLocation);
148 return 1;
149}
150
151static int circulations(xmlNode *ptr, Z_CircRecord ***circp,
152 int *num, NMEM nmem)
153{
154 int i;
155 xmlNode *ptr0 = ptr;
156
157 for (i = 0; ptr; i++)
158 {
159 while (ptr && ptr->type != XML_ELEMENT_NODE)
160 ptr = ptr->next;
161 if (!ptr)
162 break;
163 if (!yaz_match_xsd_element(ptr, "circulation"))
164 return 0;
165 ptr = ptr->next;
166 }
167 *num = i;
168 *circp = (Z_CircRecord **) nmem_malloc(nmem, sizeof(**circp) * i);
169 ptr = ptr0;
170 for (i = 0; ptr; i++)
171 {
172 while (ptr && ptr->type != XML_ELEMENT_NODE)
173 ptr = ptr->next;
174 if (!ptr)
175 break;
176 if (!yaz_match_xsd_element(ptr, "circulation"))
177 return 0;
178 circulation(ptr->children, (*circp) + i, nmem);
179 ptr = ptr->next;
180 }
181 return 1;
182}
183
184static int holdingsRecord(xmlNode *ptr, Z_HoldingsRecord **r, NMEM nmem)
185{
187
188 *r = (Z_HoldingsRecord *)
189 nmem_malloc(nmem, sizeof(**r));
191 h = (*r)->u.holdingsAndCirc = (Z_HoldingsAndCircData *)
192 nmem_malloc(nmem, sizeof(*h));
193
194 match_element_next(&ptr, "typeOfRecord", nmem, &h->typeOfRecord);
195 match_element_next(&ptr, "encodingLevel", nmem, &h->encodingLevel);
196 match_element_next(&ptr, "format", nmem, &h->format);
197 match_element_next(&ptr, "receiptAcqStatus", nmem, &h->receiptAcqStatus);
198 match_element_next(&ptr, "generalRetention", nmem, &h->generalRetention);
199 match_element_next(&ptr, "completeness", nmem, &h->completeness);
200 match_element_next(&ptr, "dateOfReport", nmem, &h->dateOfReport);
201 match_element_next(&ptr, "nucCode", nmem, &h->nucCode);
202 match_element_next(&ptr, "localLocation", nmem, &h->localLocation);
203 match_element_next(&ptr, "shelvingLocation", nmem, &h->shelvingLocation);
204 match_element_next(&ptr, "callNumber", nmem, &h->callNumber);
205 match_element_next(&ptr, "shelvingData", nmem, &h->shelvingData);
206 match_element_next(&ptr, "copyNumber", nmem, &h->copyNumber);
207 match_element_next(&ptr, "publicNote", nmem, &h->publicNote);
208 match_element_next(&ptr, "reproductionNote", nmem, &h->reproductionNote);
209 match_element_next(&ptr, "termsUseRepro", nmem, &h->termsUseRepro);
210 match_element_next(&ptr, "enumAndChron", nmem, &h->enumAndChron);
211
212 h->num_volumes = 0;
213 h->volumes = 0;
214 while (ptr && ptr->type != XML_ELEMENT_NODE)
215 ptr = ptr->next;
216 if (yaz_match_xsd_element(ptr, "volumes"))
217 {
218 volumes(ptr->children, &h->volumes, &h->num_volumes, nmem);
219 ptr = ptr->next;
220 }
221
222 h->num_circulationData = 0;
223 h->circulationData = 0;
224 while (ptr && ptr->type != XML_ELEMENT_NODE)
225 ptr = ptr->next;
226 if (yaz_match_xsd_element(ptr, "circulations"))
227 {
228 circulations(ptr->children, &h->circulationData,
229 &h->num_circulationData, nmem);
230 ptr = ptr->next;
231 }
232 return 1;
233}
234
235static int yaz_xml_to_opac_ptr(yaz_marc_t mt, xmlNode *ptr,
236 Z_OPACRecord **dst,
237 NMEM nmem,
238 const Odr_oid *syntax)
239{
240 int i;
241 Z_External *ext = 0;
242 Z_OPACRecord *opac;
243 xmlNode *ptr0;
244
245 if (!nmem)
246 nmem = yaz_marc_get_nmem(mt);
247 if (!yaz_match_xsd_element(ptr, "opacRecord"))
248 return 0;
249 ptr = ptr->children;
250 while (ptr && ptr->type != XML_ELEMENT_NODE)
251 ptr = ptr->next;
252 if (!yaz_match_xsd_element(ptr, "bibliographicRecord"))
253 return 0;
254 if (!bibliographicRecord(mt, ptr->children, &ext, nmem, syntax))
255 return 0;
256 *dst = opac = (Z_OPACRecord *) nmem_malloc(nmem, sizeof(*opac));
257 opac->num_holdingsData = 0;
258 opac->holdingsData = 0;
259 opac->bibliographicRecord = ext;
260
261 ptr = ptr->next;
262 while (ptr && ptr->type != XML_ELEMENT_NODE)
263 ptr = ptr->next;
264 if (!yaz_match_xsd_element(ptr, "holdings"))
265 return 0;
266
267 ptr = ptr->children;
268 ptr0 = ptr;
269
270 for (i = 0; ptr; i++)
271 {
272 while (ptr && ptr->type != XML_ELEMENT_NODE)
273 ptr = ptr->next;
274 if (!ptr)
275 break;
276 if (!yaz_match_xsd_element(ptr, "holding"))
277 return 0;
278 ptr = ptr->next;
279 }
280 opac->num_holdingsData = i;
281 opac->holdingsData = (Z_HoldingsRecord **)
282 nmem_malloc(nmem, sizeof(*opac->holdingsData) * i);
283 ptr = ptr0;
284 for (i = 0; ptr; i++)
285 {
286 while (ptr && ptr->type != XML_ELEMENT_NODE)
287 ptr = ptr->next;
288 if (!ptr)
289 break;
290 if (!yaz_match_xsd_element(ptr, "holding"))
291 return 0;
292 if (!holdingsRecord(ptr->children, opac->holdingsData + i, nmem))
293 return 0;
294 ptr = ptr->next;
295 }
296 return 1;
297}
298
299int yaz_xml_to_opac(yaz_marc_t mt, const char *buf_in, size_t size_in,
300 Z_OPACRecord **dst, yaz_iconv_t cd, NMEM nmem,
301 const Odr_oid *syntax)
302{
303 xmlDocPtr doc = xmlParseMemory(buf_in, size_in);
304 int r = 0;
305 if (doc)
306 {
307 yaz_marc_iconv(mt, cd);
308 r = yaz_xml_to_opac_ptr(mt, xmlDocGetRootElement(doc), dst, nmem,
309 syntax);
310 xmlFreeDoc(doc);
311 }
312 return r;
313}
314
315
316#endif
317
318/*
319 * Local variables:
320 * c-basic-offset: 4
321 * c-file-style: "Stroustrup"
322 * indent-tabs-mode: nil
323 * End:
324 * vim: shiftwidth=4 tabstop=8 expandtab
325 */
326
int yaz_marc_read_xml(yaz_marc_t mt, const xmlNode *ptr)
parses MARCXML/MarcXchange/TurboMARC record from xmlNode pointer
int yaz_marc_write_iso2709(yaz_marc_t mt, WRBUF wr)
writes record in ISO2709 format
Definition marcdisp.c:1119
void yaz_marc_iconv(yaz_marc_t mt, yaz_iconv_t cd)
set iconv handle for character set conversion
Definition marcdisp.c:1387
NMEM yaz_marc_get_nmem(yaz_marc_t mt)
returns memory for MARC handle
Definition marcdisp.c:130
MARC conversion.
void * nmem_malloc(NMEM n, size_t size)
allocates memory block on NMEM handle
Definition nmem.c:145
nmem_bool_t * nmem_booldup(NMEM mem, nmem_bool_t v)
allocates and sets boolean for NMEM
Definition nmemsdup.c:48
nmem_bool_t Odr_bool
Definition odr.h:48
Header for OID database.
const Odr_oid yaz_oid_recsyn_usmarc[]
Definition oid_std.c:43
short Odr_oid
Definition oid_util.h:42
Header for Z39.50 Protocol.
Z_External * z_ext_record_oid_nmem(NMEM nmem, const Odr_oid *oid, const char *buf, int len)
encodes EXTERNAL record based on OID (NULL if not known)
Definition prt-ext.c:262
SRU private header.
int yaz_match_xsd_element(xmlNodePtr ptr, const char *elem)
Definition xml_match.c:17
int yaz_match_xsd_string_n_nmem(xmlNodePtr ptr, const char *elem, NMEM nmem, char **val, int *len)
Definition xml_match.c:29
structure for all known EXTERNALs
Definition prt-ext.h:59
Z_InternationalString * completeness
Definition z-opac.h:58
Z_InternationalString * format
Definition z-opac.h:55
Z_InternationalString * generalRetention
Definition z-opac.h:57
Z_InternationalString * nucCode
Definition z-opac.h:60
Z_InternationalString * termsUseRepro
Definition z-opac.h:68
Z_InternationalString * copyNumber
Definition z-opac.h:65
Z_InternationalString * encodingLevel
Definition z-opac.h:54
Z_Volume ** volumes
Definition z-opac.h:71
Z_CircRecord ** circulationData
Definition z-opac.h:73
Z_InternationalString * dateOfReport
Definition z-opac.h:59
Z_InternationalString * callNumber
Definition z-opac.h:63
Z_InternationalString * typeOfRecord
Definition z-opac.h:53
Z_InternationalString * localLocation
Definition z-opac.h:61
Z_InternationalString * shelvingLocation
Definition z-opac.h:62
Z_InternationalString * receiptAcqStatus
Definition z-opac.h:56
Z_InternationalString * shelvingData
Definition z-opac.h:64
Z_InternationalString * publicNote
Definition z-opac.h:66
Z_InternationalString * reproductionNote
Definition z-opac.h:67
Z_InternationalString * enumAndChron
Definition z-opac.h:69
Z_HoldingsRecord ** holdingsData
Definition z-opac.h:39
Z_External * bibliographicRecord
Definition z-opac.h:37
int num_holdingsData
Definition z-opac.h:38
string buffer
Definition wrbuf.h:43
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
WRBUF wrbuf_alloc(void)
construct WRBUF
Definition wrbuf.c:25
Header for WRBUF (growing buffer)
#define wrbuf_buf(b)
Definition wrbuf.h:270
#define wrbuf_len(b)
Definition wrbuf.h:269
static int match_element_next(xmlNode **ptr, const char *elem, NMEM nmem, char **val)
Definition xml_to_opac.c:25
static int holdingsRecord(xmlNode *ptr, Z_HoldingsRecord **r, NMEM nmem)
static int circulation(xmlNode *ptr, Z_CircRecord **circp, NMEM nmem)
static int yaz_xml_to_opac_ptr(yaz_marc_t mt, xmlNode *ptr, Z_OPACRecord **dst, NMEM nmem, const Odr_oid *syntax)
static int match_v_next(xmlNode **ptr, const char *elem, NMEM nmem, Odr_bool **val)
Definition xml_to_opac.c:39
static int volumes(xmlNode *ptr, Z_Volume ***volp, int *num, NMEM nmem)
Definition xml_to_opac.c:99
static int volume(xmlNode *ptr, Z_Volume **volp, NMEM nmem)
Definition xml_to_opac.c:89
static int circulations(xmlNode *ptr, Z_CircRecord ***circp, int *num, NMEM nmem)
int yaz_xml_to_opac(yaz_marc_t mt, const char *buf_in, size_t size_in, Z_OPACRecord **dst, yaz_iconv_t cd, NMEM nmem, const Odr_oid *syntax)
Converts XML to OPAC.
static int bibliographicRecord(yaz_marc_t mt, xmlNode *ptr, Z_External **ext, NMEM nmem, const Odr_oid *syntax)
Definition xml_to_opac.c:70
#define Z_HoldingsRecord_holdingsAndCirc
Definition z-opac.h:48