YAZ 5.35.1
srw.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 <stdlib.h>
14
15#include <yaz/srw.h>
16#include <yaz/wrbuf.h>
17#include <yaz/nmem_xml.h>
18#if YAZ_HAVE_XML2
19#include <libxml/parser.h>
20#include <libxml/tree.h>
21#include <assert.h>
22#include <yaz/facet.h>
23#include <yaz/proto.h>
24#include "sru-p.h"
25
26char *yaz_negotiate_sru_version(char *input_ver)
27{
28 if (!input_ver)
29 return "2.0";
30 if (!strcmp(input_ver, "1.1"))
31 return "1.1";
32 if (!strncmp(input_ver, "1.", 2))
33 return "1.2";
34 if (!strncmp(input_ver, "2.", 2))
35 return "2.0";
36 return 0;
37}
38
39static int yaz_srw_record(ODR o, xmlNodePtr pptr, Z_SRW_record *rec,
40 Z_SRW_extra_record **extra,
41 void *client_data, int version2)
42{
43 if (o->direction == ODR_DECODE)
44 {
46
47 char *spack = 0;
48 xmlNodePtr ptr;
49#ifdef Z_SRW_packed
50 rec->packing = 0;
51#endif
52 rec->recordSchema = 0;
53 rec->recordData_buf = 0;
54 rec->recordData_len = 0;
55 rec->recordPosition = 0;
56 *extra = 0;
57
60 ex.recordIdentifier = 0;
61
62 for (ptr = pptr->children; ptr; ptr = ptr->next)
63 {
64
65 if (yaz_match_xsd_string(ptr, "recordSchema", o,
66 &rec->recordSchema))
67 ;
68 else if (yaz_match_xsd_string(ptr, "recordPacking", o, &spack))
69 ; /* can't rely on it: in SRU 2.0 it's different semantics */
70 else if (yaz_match_xsd_integer(ptr, "recordPosition", o,
71 &rec->recordPosition))
72 ;
73 else if (yaz_match_xsd_element(ptr, "recordData"))
74 {
75 /* we assume XML packing, if any element nodes exist below
76 recordData. Unfortunately, in SRU 2.0 recordPacking
77 means something different */
78 xmlNode *p = ptr->children;
79 for (; p; p = p->next)
80 if (p->type == XML_ELEMENT_NODE)
81 break;
82 if (p)
83 {
85 ptr, "recordData", o,
86 &rec->recordData_buf, &rec->recordData_len, 1);
88 }
89 else
90 {
92 ptr, "recordData", o,
93 &rec->recordData_buf, &rec->recordData_len);
95 }
96 }
97 else if (yaz_match_xsd_XML_n(ptr, "extraRecordData", o,
100 ;
101 else
102 yaz_match_xsd_string(ptr, "recordIdentifier", o,
103 &ex.recordIdentifier);
104 }
106 {
107 *extra = (Z_SRW_extra_record *)
108 odr_malloc(o, sizeof(Z_SRW_extra_record));
109 memcpy(*extra, &ex, sizeof(Z_SRW_extra_record));
110 }
111 }
112 else if (o->direction == ODR_ENCODE)
113 {
114 xmlNodePtr ptr = pptr;
115 int pack = rec->recordPacking;
116 const char *spack = yaz_srw_pack_to_str(pack);
117
118 /* recordSchema and recordData are required */
119 if (!rec->recordSchema)
120 xmlNewChild(ptr, 0, BAD_CAST "recordSchema", 0);
121 else
122 add_xsd_string(ptr, "recordSchema", rec->recordSchema);
123 if (spack)
124 {
125 if (version2)
126 add_xsd_string(ptr, "recordXMLEscaping", spack);
127 else
128 add_xsd_string(ptr, "recordPacking", spack);
129 }
130 if (!rec->recordData_buf)
131 xmlNewChild(ptr, 0, BAD_CAST "recordData", 0);
132 else
133 {
134 switch (pack)
135 {
137 add_xsd_string_n(ptr, "recordData", rec->recordData_buf,
138 rec->recordData_len);
139 break;
141 add_XML_n(ptr, "recordData", rec->recordData_buf,
142 rec->recordData_len, 0);
143 break;
145 add_xsd_string_n(ptr, "recordData", rec->recordData_buf,
146 rec->recordData_len);
147 break;
148 }
149 }
150 if (rec->recordPosition)
151 add_xsd_integer(ptr, "recordPosition", rec->recordPosition );
152 if (extra && *extra)
153 {
154 if ((*extra)->recordIdentifier)
155 add_xsd_string(ptr, "recordIdentifier",
156 (*extra)->recordIdentifier);
157 if ((*extra)->extraRecordData_buf)
158 add_XML_n(ptr, "extraRecordData",
159 (*extra)->extraRecordData_buf,
160 (*extra)->extraRecordData_len, 0);
161 }
162 }
163 return 0;
164}
165
166static int yaz_srw_records(ODR o, xmlNodePtr pptr, Z_SRW_record **recs,
167 Z_SRW_extra_record ***extra,
168 int *num, void *client_data, int version2)
169{
170 if (o->direction == ODR_DECODE)
171 {
172 int i;
173 xmlNodePtr ptr;
174 *num = 0;
175 for (ptr = pptr->children; ptr; ptr = ptr->next)
176 {
177 if (ptr->type == XML_ELEMENT_NODE &&
178 !xmlStrcmp(ptr->name, BAD_CAST "record"))
179 (*num)++;
180 }
181 if (!*num)
182 return 1;
183 *recs = (Z_SRW_record *) odr_malloc(o, *num * sizeof(**recs));
184 *extra = (Z_SRW_extra_record **) odr_malloc(o, *num * sizeof(**extra));
185 for (i = 0, ptr = pptr->children; ptr; ptr = ptr->next)
186 {
187 if (ptr->type == XML_ELEMENT_NODE &&
188 !xmlStrcmp(ptr->name, BAD_CAST "record"))
189 {
190 yaz_srw_record(o, ptr, *recs + i, *extra + i, client_data, 0);
191 i++;
192 }
193 }
194 }
195 else if (o->direction == ODR_ENCODE)
196 {
197 int i;
198 for (i = 0; i < *num; i++)
199 {
200 xmlNodePtr rptr = xmlNewChild(pptr, 0, BAD_CAST "record",
201 0);
202 yaz_srw_record(o, rptr, (*recs)+i, (*extra ? *extra + i : 0),
203 client_data, version2);
204 }
205 }
206 return 0;
207}
208
209static int yaz_srw_version(ODR o, xmlNodePtr pptr, Z_SRW_recordVersion *rec,
210 void *client_data, const char *ns)
211{
212 if (o->direction == ODR_DECODE)
213 {
214 xmlNodePtr ptr;
215 rec->versionType = 0;
216 rec->versionValue = 0;
217 for (ptr = pptr->children; ptr; ptr = ptr->next)
218 {
219
220 if (yaz_match_xsd_string(ptr, "versionType", o,
221 &rec->versionType))
222 ;
223 else
224 yaz_match_xsd_string(ptr, "versionValue", o,
225 &rec->versionValue);
226 }
227 }
228 else if (o->direction == ODR_ENCODE)
229 {
230 xmlNodePtr ptr = pptr;
231 add_xsd_string(ptr, "versionType", rec->versionType);
232 add_xsd_string(ptr, "versionValue", rec->versionValue);
233 }
234 return 0;
235}
236
237static int yaz_srw_versions(ODR o, xmlNodePtr pptr,
238 Z_SRW_recordVersion **vers,
239 int *num, void *client_data, const char *ns)
240{
241 if (o->direction == ODR_DECODE)
242 {
243 int i;
244 xmlNodePtr ptr;
245 *num = 0;
246 for (ptr = pptr->children; ptr; ptr = ptr->next)
247 {
248 if (ptr->type == XML_ELEMENT_NODE &&
249 !xmlStrcmp(ptr->name, BAD_CAST "recordVersion"))
250 (*num)++;
251 }
252 if (!*num)
253 return 1;
254 *vers = (Z_SRW_recordVersion *) odr_malloc(o, *num * sizeof(**vers));
255 for (i = 0, ptr = pptr->children; ptr; ptr = ptr->next)
256 {
257 if (ptr->type == XML_ELEMENT_NODE &&
258 !xmlStrcmp(ptr->name, BAD_CAST "recordVersion"))
259 {
260 yaz_srw_version(o, ptr, *vers + i, client_data, ns);
261 i++;
262 }
263 }
264 }
265 else if (o->direction == ODR_ENCODE)
266 {
267 int i;
268 for (i = 0; i < *num; i++)
269 {
270 xmlNodePtr rptr = xmlNewChild(pptr, 0, BAD_CAST "version",
271 0);
272 yaz_srw_version(o, rptr, (*vers)+i, client_data, ns);
273 }
274 }
275 return 0;
276}
277
279{
280 Odr_int freq;
281 Z_FacetTerm *facet_term;
282 const char *freq_string = yaz_element_attribute_value_get(
283 node, "facetvalue", "est_representation");
284 if (freq_string)
285 freq = odr_atoi(freq_string);
286 else
287 freq = -1;
288
289 facet_term = facet_term_create_cstr(odr,
290 nmem_text_node_cdata(node->children, odr_getmem(odr)), freq);
291 return facet_term;
292}
293
295{
296 Z_AttributeList *list;
297 Z_FacetField *facet_field;
298 int num_terms = 0;
299 int index = 0;
300 xmlNodePtr node;
301 /* USE attribute */
302 const char* name = yaz_element_attribute_value_get(ptr, "facet", "code");
303 yaz_log(YLOG_DEBUG, "sru-proxy facet type: %s", name);
304
306 for (node = ptr->children; node; node = node->next) {
307 if (yaz_match_xsd_element(node, "facetvalue"))
308 num_terms++;
309 }
310 facet_field = facet_field_create(odr, list, num_terms);
311 index = 0;
312 for (node = ptr->children; node; node = node->next)
313 {
314 if (yaz_match_xsd_element(node, "facetvalue"))
315 {
316 facet_field_term_set(odr, facet_field,
318 index);
319 index++;
320 }
321 }
322 return facet_field;
323}
324
325static int yaz_sru_proxy_decode_facets(ODR o, xmlNodePtr root,
326 Z_FacetList **facetList)
327{
328 xmlNodePtr ptr;
329
330 for (ptr = root->children; ptr; ptr = ptr->next)
331 {
332 if (yaz_match_xsd_element(ptr, "facets"))
333 {
334 xmlNodePtr node;
335 Z_FacetList *facet_list;
336 int num_facets = 0;
337 for (node = ptr->children; node; node= node->next)
338 {
339 if (node->type == XML_ELEMENT_NODE)
340 num_facets++;
341 }
342 facet_list = facet_list_create(o, num_facets);
343 num_facets = 0;
344 for (node = ptr->children; node; node= node->next)
345 {
346 if (yaz_match_xsd_element(node, "facet"))
347 {
349 o, facet_list,
350 yaz_sru_proxy_decode_facet_field(o, node), num_facets);
351 num_facets++;
352 }
353 }
354 *facetList = facet_list;
355 break;
356 }
357 }
358 return 0;
359}
360
361
362
363static int yaz_srw_decode_diagnostics(ODR o, xmlNodePtr pptr,
364 Z_SRW_diagnostic **recs, int *num,
365 void *client_data, const char *ns)
366{
367 int i;
368 xmlNodePtr ptr;
369 *num = 0;
370 for (ptr = pptr; ptr; ptr = ptr->next)
371 {
372 if (ptr->type == XML_ELEMENT_NODE &&
373 !xmlStrcmp(ptr->name, BAD_CAST "diagnostic"))
374 (*num)++;
375 }
376 if (!*num)
377 return 1;
378 *recs = (Z_SRW_diagnostic *) odr_malloc(o, *num * sizeof(**recs));
379 for (i = 0; i < *num; i++)
380 {
381 (*recs)[i].uri = 0;
382 (*recs)[i].details = 0;
383 (*recs)[i].message = 0;
384 }
385 for (i = 0, ptr = pptr; ptr; ptr = ptr->next)
386 {
387 if (ptr->type == XML_ELEMENT_NODE &&
388 !xmlStrcmp(ptr->name, BAD_CAST "diagnostic"))
389 {
390 xmlNodePtr rptr;
391 (*recs)[i].uri = 0;
392 (*recs)[i].details = 0;
393 (*recs)[i].message = 0;
394 for (rptr = ptr->children; rptr; rptr = rptr->next)
395 {
396 if (yaz_match_xsd_string(rptr, "uri", o, &(*recs)[i].uri))
397 ;
398 else if (yaz_match_xsd_string(rptr, "details", o,
399 &(*recs)[i].details))
400 ;
401 else
402 yaz_match_xsd_string(rptr, "message", o,
403 &(*recs)[i].message);
404 }
405 i++;
406 }
407 }
408 return 0;
409}
410
411int sru_decode_surrogate_diagnostics(const char *buf, size_t len,
412 Z_SRW_diagnostic **diag,
413 int *num, ODR odr)
414{
415 int ret = 0;
416 xmlDocPtr doc = xmlParseMemory(buf, len);
417 if (doc)
418 {
419 xmlNodePtr ptr = xmlDocGetRootElement(doc);
420 while (ptr && ptr->type != XML_ELEMENT_NODE)
421 ptr = ptr->next;
422 if (ptr && ptr->ns
423 && !xmlStrcmp(ptr->ns->href,
424 BAD_CAST "http://www.loc.gov/zing/srw/diagnostic/"))
425 {
426 ret = yaz_srw_decode_diagnostics(odr, ptr, diag, num, 0, 0);
427 }
428 xmlFreeDoc(doc);
429 }
430 return ret;
431}
432
433static int yaz_srw_diagnostics(ODR o, xmlNodePtr pptr, Z_SRW_diagnostic **recs,
434 int *num, void *client_data, const char *ns,
435 int version2)
436{
437 if (o->direction == ODR_DECODE)
438 {
439 return yaz_srw_decode_diagnostics(o, pptr->children, recs, num, client_data, ns);
440 }
441 else if (o->direction == ODR_ENCODE)
442 {
443 int i;
444 xmlNsPtr ns_diag =
445 xmlNewNs(pptr, BAD_CAST (version2 ?
447 BAD_CAST "diag" );
448 for (i = 0; i < *num; i++)
449 {
450 const char *std_diag = "info:srw/diagnostic/1/";
451 const char *ucp_diag = "info:srw/diagnostic/12/";
452 xmlNodePtr rptr = xmlNewChild(pptr, ns_diag,
453 BAD_CAST "diagnostic", 0);
454 add_xsd_string(rptr, "uri", (*recs)[i].uri);
455 add_xsd_string(rptr, "details", (*recs)[i].details);
456 if ((*recs)[i].message)
457 add_xsd_string(rptr, "message", (*recs)[i].message);
458 else if ((*recs)[i].uri )
459 {
460 if (!strncmp((*recs)[i].uri, std_diag, strlen(std_diag)))
461 {
462 int no = atoi((*recs)[i].uri + strlen(std_diag));
463 const char *message = yaz_diag_srw_str(no);
464 if (message)
465 add_xsd_string(rptr, "message", message);
466 }
467 else if (!strncmp((*recs)[i].uri, ucp_diag, strlen(ucp_diag)))
468 {
469 int no = atoi((*recs)[i].uri + strlen(ucp_diag));
470 const char *message = yaz_diag_sru_update_str(no);
471 if (message)
472 add_xsd_string(rptr, "message", message);
473 }
474 }
475 }
476 }
477 return 0;
478}
479
480static int yaz_srw_term(ODR o, xmlNodePtr pptr, Z_SRW_scanTerm *term,
481 void *client_data, const char *ns)
482{
483 if (o->direction == ODR_DECODE)
484 {
485 xmlNodePtr ptr;
486 term->value = 0;
487 term->numberOfRecords = 0;
488 term->displayTerm = 0;
489 term->whereInList = 0;
490 for (ptr = pptr->children; ptr; ptr = ptr->next)
491 {
492 if (yaz_match_xsd_string(ptr, "value", o, &term->value))
493 ;
494 else if (yaz_match_xsd_integer(ptr, "numberOfRecords", o,
495 &term->numberOfRecords))
496 ;
497 else if (yaz_match_xsd_string(ptr, "displayTerm", o,
498 &term->displayTerm))
499 ;
500 else
501 yaz_match_xsd_string(ptr, "whereInList", o, &term->whereInList);
502 }
503 }
504 else if (o->direction == ODR_ENCODE)
505 {
506 xmlNodePtr ptr = pptr;
507 add_xsd_string(ptr, "value", term->value);
508 add_xsd_integer(ptr, "numberOfRecords", term->numberOfRecords);
509 add_xsd_string(ptr, "displayTerm", term->displayTerm);
510 add_xsd_string(ptr, "whereInList", term->whereInList);
511 }
512 return 0;
513}
514
515static int yaz_srw_terms(ODR o, xmlNodePtr pptr, Z_SRW_scanTerm **terms,
516 int *num, void *client_data, const char *ns)
517{
518 if (o->direction == ODR_DECODE)
519 {
520 int i;
521 xmlNodePtr ptr;
522 *num = 0;
523 for (ptr = pptr->children; ptr; ptr = ptr->next)
524 {
525 if (ptr->type == XML_ELEMENT_NODE &&
526 !xmlStrcmp(ptr->name, BAD_CAST "term"))
527 (*num)++;
528 }
529 if (!*num)
530 return 1;
531 *terms = (Z_SRW_scanTerm *) odr_malloc(o, *num * sizeof(**terms));
532 for (i = 0, ptr = pptr->children; ptr; ptr = ptr->next, i++)
533 {
534 if (ptr->type == XML_ELEMENT_NODE &&
535 !xmlStrcmp(ptr->name, BAD_CAST "term"))
536 yaz_srw_term(o, ptr, (*terms)+i, client_data, ns);
537 }
538 }
539 else if (o->direction == ODR_ENCODE)
540 {
541 int i;
542 for (i = 0; i < *num; i++)
543 {
544 xmlNodePtr rptr = xmlNewChild(pptr, 0, BAD_CAST "term", 0);
545 yaz_srw_term(o, rptr, (*terms)+i, client_data, ns);
546 }
547 }
548 return 0;
549}
550
551static void encode_echoed_args(xmlNodePtr ptr, Z_SRW_PDU *p, const char *name)
552{
554 if (ea)
555 {
556 xmlNode *p1 = xmlNewChild(ptr, 0, BAD_CAST name, 0);
557 xmlNode *p2 = 0;
558 for (; ea; ea = ea->next)
559 {
560 if (ea->name && ea->name[0] == 'x' && ea->name[1] == '-')
561 {
562 /* not really according to XSD as of July 2014 */
563 if (!p2)
564 p2 = xmlNewChild(p1, 0,
565 BAD_CAST "extraRequestData", 0);
566 /* skip +2: "x-" in element */
567 add_xsd_string(p2, ea->name + 2, ea->value);
568 }
569 else
570 add_xsd_string(p1, ea->name, ea->value);
571 }
572 }
573}
574
575int yaz_srw_codec(ODR o, void * vptr, Z_SRW_PDU **handler_data,
576 void *client_data, const char *ns)
577{
578 xmlNodePtr pptr = (xmlNodePtr) vptr;
579 if (o->direction == ODR_DECODE)
580 {
581 Z_SRW_PDU **p = handler_data;
582 xmlNodePtr method = pptr->children;
583 char *neg_version;
584
585 while (method && method->type == XML_TEXT_NODE)
586 method = method->next;
587
588 if (!method)
589 return -1;
590 if (method->type != XML_ELEMENT_NODE)
591 return -1;
592
594
595 if (!xmlStrcmp(method->name, BAD_CAST "searchRetrieveRequest"))
596 {
597 xmlNodePtr ptr = method->children;
599 char *recordPacking = 0;
600 char *recordXMLEscaping = 0;
601 const char *facetLimit = 0;
602 const char *facetStart = 0;
603 const char *facetSort = 0;
604
605 (*p)->which = Z_SRW_searchRetrieve_request;
606 req = (*p)->u.request = (Z_SRW_searchRetrieveRequest *)
607 odr_malloc(o, sizeof(*req));
608 req->queryType = "cql";
609 req->query = 0;
611 req->sort.none = 0;
612 req->startRecord = 0;
613 req->maximumRecords = 0;
614 req->recordSchema = 0;
615 req->recordPacking = 0;
616 req->packing = 0;
617 req->recordXPath = 0;
618 req->resultSetTTL = 0;
619 req->stylesheet = 0;
620 req->database = 0;
621
622 for (; ptr; ptr = ptr->next)
623 {
624 if (yaz_match_xsd_string(ptr, "version", o,
625 &(*p)->srw_version))
626 ;
627 else if (yaz_match_xsd_string(ptr, "queryType", o,
628 &req->queryType))
629 ;
630 else if (yaz_match_xsd_string(ptr, "query", o,
631 &req->query))
632 ;
633 else if (yaz_match_xsd_string(ptr, "pQuery", o,
634 &req->query))
635 req->queryType = "pqf";
636 else if (yaz_match_xsd_string(ptr, "xQuery", o,
637 &req->query))
638 req->queryType = "xcql";
639 else if (yaz_match_xsd_integer(ptr, "startRecord", o,
640 &req->startRecord))
641 ;
642 else if (yaz_match_xsd_integer(ptr, "maximumRecords", o,
643 &req->maximumRecords))
644 ;
645 else if (yaz_match_xsd_string(ptr, "recordPacking", o,
646 &recordPacking))
647 ;
648 else if (yaz_match_xsd_string(ptr, "recordXMLEscaping", o,
649 &recordXMLEscaping))
650 ;
651 else if (yaz_match_xsd_string(ptr, "recordSchema", o,
652 &req->recordSchema))
653 ;
654 else if (yaz_match_xsd_string(ptr, "recordXPath", o,
655 &req->recordXPath))
656 ;
657 else if (yaz_match_xsd_integer(ptr, "resultSetTTL", o,
658 &req->resultSetTTL))
659 ;
660 else if (yaz_match_xsd_string(ptr, "sortKeys", o,
661 &req->sort.sortKeys))
663 else if (yaz_match_xsd_string(ptr, "stylesheet", o,
664 &req->stylesheet))
665 ;
666 else if (yaz_match_xsd_string(ptr, "database", o,
667 &req->database))
668 ;
669 else if (yaz_match_xsd_string(ptr, "facetLimit", o,
670 (char**) &facetLimit))
671 ;
672 else if (yaz_match_xsd_string(ptr, "facetStart", o,
673 (char**) &facetStart))
674 ;
675 else if (yaz_match_xsd_string(ptr, "facetSort", o,
676 (char**) &facetSort))
677 ;
678 else
679 ;
680 }
681 if (!req->query)
682 {
683 /* should put proper diagnostic here */
684 return -1;
685 }
686 if (!strcmp((*p)->srw_version, "2.0"))
687 {
688 req->recordPacking = recordXMLEscaping;
689 req->packing = recordPacking;
690 }
691 else
692 {
693 req->recordPacking = recordPacking;
694 }
695 yaz_sru_facet_request(o, &req->facetList, &facetLimit, &facetStart,
696 &facetSort);
697 }
698 else if (!xmlStrcmp(method->name, BAD_CAST "searchRetrieveResponse"))
699 {
700 xmlNodePtr ptr = method->children;
702
703 (*p)->which = Z_SRW_searchRetrieve_response;
704 res = (*p)->u.response = (Z_SRW_searchRetrieveResponse *)
705 odr_malloc(o, sizeof(*res));
706
707 res->numberOfRecords = 0;
708 res->resultCountPrecision = 0;
709 res->resultSetId = 0;
710 res->resultSetIdleTime = 0;
711 res->records = 0;
712 res->num_records = 0;
713 res->diagnostics = 0;
714 res->num_diagnostics = 0;
715 res->nextRecordPosition = 0;
716 res->facetList = 0;
717 res->suggestions = 0;
718
719 for (; ptr; ptr = ptr->next)
720 {
721 if (yaz_match_xsd_string(ptr, "version", o,
722 &(*p)->srw_version))
723 ;
724 else if (yaz_match_xsd_XML_n(ptr, "extraResponseData", o,
725 &(*p)->extraResponseData_buf,
726 &(*p)->extraResponseData_len))
727 ;
728 else if (yaz_match_xsd_integer(ptr, "numberOfRecords", o,
729 &res->numberOfRecords))
730 ;
731 else if (yaz_match_xsd_string(ptr, "resultCountPrecision", o,
733 ;
734 else if (yaz_match_xsd_string(ptr, "resultSetId", o,
735 &res->resultSetId))
736 ;
737 else if (yaz_match_xsd_integer(ptr, "resultSetIdleTime", o,
738 &res->resultSetIdleTime))
739 ;
740 else if (yaz_match_xsd_integer(ptr, "resultSetTTL", o,
741 &res->resultSetIdleTime))
742 ;
743 else if (yaz_match_xsd_element(ptr, "records"))
744 yaz_srw_records(o, ptr, &res->records,
745 &res->extra_records,
746 &res->num_records, client_data, 0);
747 else if (yaz_match_xsd_integer(ptr, "nextRecordPosition", o,
748 &res->nextRecordPosition))
749 ;
750 else if (yaz_match_xsd_element(ptr, "diagnostics"))
751 yaz_srw_diagnostics(o, ptr, &res->diagnostics,
752 &res->num_diagnostics,
753 client_data, ns, 0);
754 else if (yaz_match_xsd_element(ptr, "facet_analysis"))
756 else if (yaz_match_xsd_element(ptr, "facetedResults"))
757 yaz_sru_facet_response(o, &res->facetList, ptr);
758 }
759 }
760 else if (!xmlStrcmp(method->name, BAD_CAST "explainRequest"))
761 {
763 xmlNodePtr ptr = method->children;
764
765 (*p)->which = Z_SRW_explain_request;
766 req = (*p)->u.explain_request = (Z_SRW_explainRequest *)
767 odr_malloc(o, sizeof(*req));
768 req->recordPacking = 0;
769 req->packing = 0;
770 req->database = 0;
771 req->stylesheet = 0;
772 for (; ptr; ptr = ptr->next)
773 {
774 if (yaz_match_xsd_string(ptr, "version", o,
775 &(*p)->srw_version))
776 ;
777 else if (yaz_match_xsd_XML_n(ptr, "extraResponseData", o,
778 &(*p)->extraResponseData_buf,
779 &(*p)->extraResponseData_len))
780 ;
781 else if (yaz_match_xsd_string(ptr, "stylesheet", o,
782 &req->stylesheet))
783 ;
784 else if (yaz_match_xsd_string(ptr, "recordPacking", o,
785 &req->recordPacking))
786 ;
787 else
788 yaz_match_xsd_string(ptr, "database", o, &req->database);
789 }
790 }
791 else if (!xmlStrcmp(method->name, BAD_CAST "explainResponse"))
792 {
794 xmlNodePtr ptr = method->children;
795
796 (*p)->which = Z_SRW_explain_response;
797 res = (*p)->u.explain_response = (Z_SRW_explainResponse*)
798 odr_malloc(o, sizeof(*res));
799 res->diagnostics = 0;
800 res->num_diagnostics = 0;
801 res->record.recordSchema = 0;
802 res->record.recordData_buf = 0;
803 res->record.recordData_len = 0;
804 res->record.recordPosition = 0;
805
806 for (; ptr; ptr = ptr->next)
807 {
808 if (yaz_match_xsd_string(ptr, "version", o,
809 &(*p)->srw_version))
810 ;
811 else if (yaz_match_xsd_XML_n(ptr, "extraResponseData", o,
812 &(*p)->extraResponseData_buf,
813 &(*p)->extraResponseData_len))
814 ;
815 else if (yaz_match_xsd_element(ptr, "record"))
816 yaz_srw_record(o, ptr, &res->record, &res->extra_record,
817 client_data, 0);
818 else if (yaz_match_xsd_element(ptr, "diagnostics"))
819 yaz_srw_diagnostics(o, ptr, &res->diagnostics,
820 &res->num_diagnostics,
821 client_data, ns, 0);
822 ;
823 }
824 }
825 else if (!xmlStrcmp(method->name, BAD_CAST "scanRequest"))
826 {
828 xmlNodePtr ptr = method->children;
829
830 (*p)->which = Z_SRW_scan_request;
831 req = (*p)->u.scan_request = (Z_SRW_scanRequest *)
832 odr_malloc(o, sizeof(*req));
833 req->queryType = "cql";
834 req->scanClause = 0;
835 req->responsePosition = 0;
836 req->maximumTerms = 0;
837 req->stylesheet = 0;
838 req->database = 0;
839
840 for (; ptr; ptr = ptr->next)
841 {
842 if (yaz_match_xsd_string(ptr, "version", o,
843 &(*p)->srw_version))
844 ;
845 else if (yaz_match_xsd_XML_n(ptr, "extraResponseData", o,
846 &(*p)->extraResponseData_buf,
847 &(*p)->extraResponseData_len))
848 ;
849 else if (yaz_match_xsd_string(ptr, "scanClause", o,
850 &req->scanClause))
851 ;
852 else if (yaz_match_xsd_string(ptr, "pScanClause", o,
853 &req->scanClause))
854 {
855 req->queryType = "pqf";
856 }
857 else if (yaz_match_xsd_integer(ptr, "responsePosition", o,
858 &req->responsePosition))
859 ;
860 else if (yaz_match_xsd_integer(ptr, "maximumTerms", o,
861 &req->maximumTerms))
862 ;
863 else if (yaz_match_xsd_string(ptr, "stylesheet", o,
864 &req->stylesheet))
865 ;
866 else
867 yaz_match_xsd_string(ptr, "database", o, &req->database);
868 }
869 }
870 else if (!xmlStrcmp(method->name, BAD_CAST "scanResponse"))
871 {
873 xmlNodePtr ptr = method->children;
874
875 (*p)->which = Z_SRW_scan_response;
876 res = (*p)->u.scan_response = (Z_SRW_scanResponse *)
877 odr_malloc(o, sizeof(*res));
878 res->terms = 0;
879 res->num_terms = 0;
880 res->diagnostics = 0;
881 res->num_diagnostics = 0;
882
883 for (; ptr; ptr = ptr->next)
884 {
885 if (yaz_match_xsd_string(ptr, "version", o,
886 &(*p)->srw_version))
887 ;
888 else if (yaz_match_xsd_XML_n(ptr, "extraResponseData", o,
889 &(*p)->extraResponseData_buf,
890 &(*p)->extraResponseData_len))
891 ;
892 else if (yaz_match_xsd_element(ptr, "terms"))
893 yaz_srw_terms(o, ptr, &res->terms,
894 &res->num_terms, client_data,
895 ns);
896 else if (yaz_match_xsd_element(ptr, "diagnostics"))
897 yaz_srw_diagnostics(o, ptr, &res->diagnostics,
898 &res->num_diagnostics,
899 client_data, ns, 0);
900 }
901 }
902 else
903 {
904 *p = 0;
905 return -1;
906 }
907 neg_version = yaz_negotiate_sru_version((*p)->srw_version);
908 if (neg_version)
909 (*p)->srw_version = neg_version;
910 }
911 else if (o->direction == ODR_ENCODE)
912 {
913 Z_SRW_PDU **p = handler_data;
914 xmlNsPtr ns_srw;
915 xmlNodePtr ptr = 0;
916 int version2 = !(*p)->srw_version ||
917 strcmp((*p)->srw_version, "2.") > 0;
918 if ((*p)->which == Z_SRW_searchRetrieve_request)
919 {
920 Z_SRW_searchRetrieveRequest *req = (*p)->u.request;
921 const char *queryType = req->queryType;
922 if (version2)
923 ns = "http://docs.oasis-open.org/ns/search-ws/sruRequest";
924 ptr = xmlNewChild(pptr, 0, BAD_CAST "searchRetrieveRequest", 0);
925 ns_srw = xmlNewNs(ptr, BAD_CAST ns, BAD_CAST "zs");
926 xmlSetNs(ptr, ns_srw);
927
928 if (!version2)
929 add_xsd_string(ptr, "version", (*p)->srw_version);
930 if (version2)
931 {
932 add_xsd_string(ptr, "query", req->query);
933 }
934 else
935 {
936 if (!queryType || !strcmp(queryType, "cql"))
937 add_xsd_string(ptr, "query", req->query);
938 else if (!strcmp(queryType, "xcql"))
939 add_xsd_string(ptr, "xQuery", req->query);
940 else if (!strcmp(queryType, "pqf"))
941 add_xsd_string(ptr, "pQuery", req->query);
942 queryType = 0;
943 }
944 add_xsd_integer(ptr, "startRecord", req->startRecord);
945 add_xsd_integer(ptr, "maximumRecords", req->maximumRecords);
946 if (version2)
947 add_xsd_string(ptr, "recordXMLEscaping", req->recordPacking);
948 else
949 add_xsd_string(ptr, "recordPacking", req->recordPacking);
950 add_xsd_string(ptr, "recordSchema", req->recordSchema);
951 add_xsd_string(ptr, "recordXPath", req->recordXPath);
952 add_xsd_integer(ptr, "resultSetTTL", req->resultSetTTL);
953 add_xsd_string(ptr, "stylesheet", req->stylesheet);
954 add_xsd_string(ptr, "queryType", queryType);
955 switch (req->sort_type)
956 {
958 break;
960 add_xsd_string(ptr, "sortKeys", req->sort.sortKeys);
961 break;
963 add_xsd_string(ptr, "xSortKeys", req->sort.xSortKeys);
964 break;
965 }
966 /* still unsupported are: renderedBy, httpAccept, responseType */
967 add_xsd_string(ptr, "database", req->database);
968 if (version2)
969 add_xsd_string(ptr, "recordPacking", req->packing);
970 {
971 const char *limit = 0;
972 const char *start = 0;
973 const char *sort = 0;
974 yaz_sru_facet_request(o, &req->facetList, &limit, &start,
975 &sort);
976 add_xsd_string(ptr, "facetLimit", limit);
977 add_xsd_string(ptr, "facetStart", start);
978 add_xsd_string(ptr, "facetSort", sort);
979 }
980 }
981 else if ((*p)->which == Z_SRW_searchRetrieve_response)
982 {
983 Z_SRW_searchRetrieveResponse *res = (*p)->u.response;
984 if (version2)
985 ns = "http://docs.oasis-open.org/ns/search-ws/sruResponse";
986 ptr = xmlNewChild(pptr, 0, BAD_CAST "searchRetrieveResponse", 0);
987 ns_srw = xmlNewNs(ptr, BAD_CAST ns, BAD_CAST "zs");
988 xmlSetNs(ptr, ns_srw);
989
990 if (!version2)
991 add_xsd_string(ptr, "version", (*p)->srw_version);
992 add_xsd_integer(ptr, "numberOfRecords", res->numberOfRecords);
993 add_xsd_string(ptr, "resultSetId", res->resultSetId);
994 if (!version2)
995 add_xsd_integer(ptr, "resultSetIdleTime",
996 res->resultSetIdleTime);
997 if (res->num_records)
998 {
999 xmlNodePtr rptr = xmlNewChild(ptr, 0, BAD_CAST "records", 0);
1000 yaz_srw_records(o, rptr, &res->records, &res->extra_records,
1001 &res->num_records,
1002 client_data, version2);
1003 }
1004 add_xsd_integer(ptr, "nextRecordPosition",
1005 res->nextRecordPosition);
1006 encode_echoed_args(ptr, *p, "echoedSearchRetrieveRequest");
1007 if (res->num_diagnostics)
1008 {
1009 xmlNodePtr rptr = xmlNewChild(ptr, 0, BAD_CAST "diagnostics",
1010 0);
1011 yaz_srw_diagnostics(o, rptr, &res->diagnostics,
1012 &res->num_diagnostics, client_data, ns,
1013 version2);
1014 }
1015 if (version2)
1016 {
1017 if (ptr && (*p)->extraResponseData_len)
1018 add_XML_n(ptr, "extraResponseData",
1019 (*p)->extraResponseData_buf,
1020 (*p)->extraResponseData_len, ns_srw);
1021 add_xsd_integer(ptr, "resultSetTTL", res->resultSetIdleTime);
1022 add_xsd_string(ptr, "resultCountPrecision",
1024 yaz_sru_facet_response(o, &res->facetList, ptr);
1025 return 0; /* so we don't make extra response data twice */
1026 }
1027 }
1028 else if ((*p)->which == Z_SRW_explain_request)
1029 {
1030 Z_SRW_explainRequest *req = (*p)->u.explain_request;
1031 if (version2)
1032 ns = "http://docs.oasis-open.org/ns/search-ws/sruRequest";
1033 ptr = xmlNewChild(pptr, 0, BAD_CAST "explainRequest", 0);
1034 ns_srw = xmlNewNs(ptr, BAD_CAST ns, BAD_CAST "zs");
1035 xmlSetNs(ptr, ns_srw);
1036
1037 if (!version2)
1038 add_xsd_string(ptr, "version", (*p)->srw_version);
1039 if (version2)
1040 {
1041 add_xsd_string(ptr, "recordXMLEscaping", req->recordPacking);
1042 add_xsd_string(ptr, "recordPacking", req->packing);
1043 }
1044 else
1045 add_xsd_string(ptr, "recordPacking", req->recordPacking);
1046 add_xsd_string(ptr, "stylesheet", req->stylesheet);
1047 add_xsd_string(ptr, "database", req->database);
1048 }
1049 else if ((*p)->which == Z_SRW_explain_response)
1050 {
1051 Z_SRW_explainResponse *res = (*p)->u.explain_response;
1052 if (version2)
1053 ns = "http://docs.oasis-open.org/ns/search-ws/sruResponse";
1054 ptr = xmlNewChild(pptr, 0, BAD_CAST "explainResponse", 0);
1055 ns_srw = xmlNewNs(ptr, BAD_CAST ns, BAD_CAST "zs");
1056 xmlSetNs(ptr, ns_srw);
1057
1058 add_xsd_string(ptr, "version", (*p)->srw_version);
1059 if (1)
1060 {
1061 xmlNodePtr ptr1 = xmlNewChild(ptr, 0, BAD_CAST "record", 0);
1062 yaz_srw_record(o, ptr1, &res->record, &res->extra_record,
1063 client_data, version2);
1064 }
1065 encode_echoed_args(ptr, *p, "echoedExplainRequest");
1066 if (res->num_diagnostics)
1067 {
1068 xmlNodePtr rptr = xmlNewChild(ptr, 0, BAD_CAST "diagnostics",
1069 0);
1070 yaz_srw_diagnostics(o, rptr, &res->diagnostics,
1071 &res->num_diagnostics, client_data, ns,
1072 version2);
1073 }
1074 }
1075 else if ((*p)->which == Z_SRW_scan_request)
1076 {
1077 Z_SRW_scanRequest *req = (*p)->u.scan_request;
1078 const char *queryType = req->queryType;
1079 if (version2)
1080 ns = "http://docs.oasis-open.org/ns/search-ws/scan";
1081 ptr = xmlNewChild(pptr, 0, BAD_CAST "scanRequest", 0);
1082 ns_srw = xmlNewNs(ptr, BAD_CAST ns, BAD_CAST "zs");
1083 xmlSetNs(ptr, ns_srw);
1084
1085 if (!version2)
1086 add_xsd_string(ptr, "version", (*p)->srw_version);
1087
1088 if (version2)
1089 {
1090 if (queryType && strcmp(queryType, "cql"))
1091 add_xsd_string(ptr, "queryType", queryType);
1092 add_xsd_string(ptr, "scanClause", req->scanClause);
1093 }
1094 else
1095 {
1096 if (!queryType || !strcmp(queryType, "cql"))
1097 add_xsd_string(ptr, "scanClause", req->scanClause);
1098 else if (!strcmp(queryType, "pqf"))
1099 add_xsd_string(ptr, "pScanClause", req->scanClause);
1100 }
1101 add_xsd_integer(ptr, "responsePosition", req->responsePosition);
1102 add_xsd_integer(ptr, "maximumTerms", req->maximumTerms);
1103 add_xsd_string(ptr, "stylesheet", req->stylesheet);
1104 add_xsd_string(ptr, "database", req->database);
1105 }
1106 else if ((*p)->which == Z_SRW_scan_response)
1107 {
1108 Z_SRW_scanResponse *res = (*p)->u.scan_response;
1109 if (version2)
1110 ns = "http://docs.oasis-open.org/ns/search-ws/scan";
1111 ptr = xmlNewChild(pptr, 0, BAD_CAST "scanResponse", 0);
1112 ns_srw = xmlNewNs(ptr, BAD_CAST ns, BAD_CAST "zs");
1113 xmlSetNs(ptr, ns_srw);
1114
1115 if (!version2)
1116 add_xsd_string(ptr, "version", (*p)->srw_version);
1117 if (res->num_terms)
1118 {
1119 xmlNodePtr rptr = xmlNewChild(ptr, 0, BAD_CAST "terms", 0);
1120 yaz_srw_terms(o, rptr, &res->terms, &res->num_terms,
1121 client_data, ns);
1122 }
1123 if (res->num_diagnostics)
1124 {
1125 xmlNodePtr rptr = xmlNewChild(ptr, 0, BAD_CAST "diagnostics",
1126 0);
1127 yaz_srw_diagnostics(o, rptr, &res->diagnostics,
1128 &res->num_diagnostics, client_data, ns,
1129 version2);
1130 }
1131 }
1132 else
1133 return -1;
1134 if (ptr && (*p)->extraResponseData_len)
1135 add_XML_n(ptr, "extraResponseData",
1136 (*p)->extraResponseData_buf,
1137 (*p)->extraResponseData_len, ns_srw);
1138
1139
1140 }
1141 return 0;
1142}
1143
1144int yaz_ucp_codec(ODR o, void * vptr, Z_SRW_PDU **handler_data,
1145 void *client_data, const char *ns_ucp_str)
1146{
1147 xmlNodePtr pptr = (xmlNodePtr) vptr;
1148 const char *ns_srw_str = YAZ_XMLNS_SRU_v1_1;
1149 if (o->direction == ODR_DECODE)
1150 {
1151 Z_SRW_PDU **p = handler_data;
1152 xmlNodePtr method = pptr->children;
1153
1154 while (method && method->type == XML_TEXT_NODE)
1155 method = method->next;
1156
1157 if (!method)
1158 return -1;
1159 if (method->type != XML_ELEMENT_NODE)
1160 return -1;
1161
1162 *p = yaz_srw_get_core_v_2_0(o);
1163
1164 if (!xmlStrcmp(method->name, BAD_CAST "updateRequest"))
1165 {
1166 xmlNodePtr ptr = method->children;
1168 char *oper = 0;
1169
1170 (*p)->which = Z_SRW_update_request;
1171 req = (*p)->u.update_request = (Z_SRW_updateRequest *)
1172 odr_malloc(o, sizeof(*req));
1173 req->database = 0;
1174 req->operation = 0;
1175 req->recordId = 0;
1176 req->recordVersions = 0;
1177 req->num_recordVersions = 0;
1178 req->record = 0;
1179 req->extra_record = 0;
1180 req->extraRequestData_buf = 0;
1181 req->extraRequestData_len = 0;
1182 req->stylesheet = 0;
1183
1184 for (; ptr; ptr = ptr->next)
1185 {
1186 if (yaz_match_xsd_string(ptr, "version", o,
1187 &(*p)->srw_version))
1188 ;
1189 else if (yaz_match_xsd_string(ptr, "action", o,
1190 &oper)){
1191 if (oper)
1192 {
1193 if (!strcmp(oper, "info:srw/action/1/delete"))
1194 req->operation = "delete";
1195 else if (!strcmp(oper,"info:srw/action/1/replace" ))
1196 req->operation = "replace";
1197 else if (!strcmp(oper, "info:srw/action/1/create"))
1198 req->operation = "insert";
1199 }
1200 }
1201 else if (yaz_match_xsd_string(ptr, "recordIdentifier", o,
1202 &req->recordId))
1203 ;
1204 else if (yaz_match_xsd_element(ptr, "recordVersions" ) )
1205 yaz_srw_versions( o, ptr, &req->recordVersions,
1206 &req->num_recordVersions, client_data,
1207 ns_ucp_str);
1208 else if (yaz_match_xsd_element(ptr, "record"))
1209 {
1210 req->record = yaz_srw_get_record(o);
1211 yaz_srw_record(o, ptr, req->record, &req->extra_record,
1212 client_data, 0);
1213 }
1214 else if (yaz_match_xsd_string(ptr, "stylesheet", o,
1215 &req->stylesheet))
1216 ;
1217 else
1218 yaz_match_xsd_string(ptr, "database", o, &req->database);
1219 }
1220 }
1221 else if (!xmlStrcmp(method->name, BAD_CAST "updateResponse"))
1222 {
1223 xmlNodePtr ptr = method->children;
1225
1226 (*p)->which = Z_SRW_update_response;
1227 res = (*p)->u.update_response = (Z_SRW_updateResponse *)
1228 odr_malloc(o, sizeof(*res));
1229
1230 res->operationStatus = 0;
1231 res->recordId = 0;
1232 res->recordVersions = 0;
1233 res->num_recordVersions = 0;
1234 res->diagnostics = 0;
1235 res->num_diagnostics = 0;
1236 res->record = 0;
1237 res->extra_record = 0;
1238 res->extraResponseData_buf = 0;
1239 res->extraResponseData_len = 0;
1240
1241 for (; ptr; ptr = ptr->next)
1242 {
1243 if (yaz_match_xsd_string(ptr, "version", o,
1244 &(*p)->srw_version))
1245 ;
1246 else if (yaz_match_xsd_string(ptr, "operationStatus", o,
1247 &res->operationStatus ))
1248 ;
1249 else if (yaz_match_xsd_string(ptr, "recordIdentifier", o,
1250 &res->recordId))
1251 ;
1252 else if (yaz_match_xsd_element(ptr, "recordVersions" ))
1253 yaz_srw_versions(o, ptr, &res->recordVersions,
1254 &res->num_recordVersions,
1255 client_data, ns_ucp_str);
1256 else if (yaz_match_xsd_element(ptr, "record"))
1257 {
1258 res->record = yaz_srw_get_record(o);
1259 yaz_srw_record(o, ptr, res->record, &res->extra_record,
1260 client_data, 0);
1261 }
1262 else if (yaz_match_xsd_element(ptr, "diagnostics"))
1263 yaz_srw_diagnostics(o, ptr, &res->diagnostics,
1264 &res->num_diagnostics,
1265 client_data, ns_ucp_str, 0);
1266 }
1267 }
1268 else if (!xmlStrcmp(method->name, BAD_CAST "explainUpdateRequest"))
1269 {
1270 }
1271 else if (!xmlStrcmp(method->name, BAD_CAST "explainUpdateResponse"))
1272 {
1273 }
1274 else
1275 {
1276 *p = 0;
1277 return -1;
1278 }
1279 }
1280 else if (o->direction == ODR_ENCODE)
1281 {
1282 Z_SRW_PDU **p = handler_data;
1283 xmlNsPtr ns_ucp, ns_srw;
1284
1285 if ((*p)->which == Z_SRW_update_request)
1286 {
1287 Z_SRW_updateRequest *req = (*p)->u.update_request;
1288 xmlNodePtr ptr = xmlNewChild(pptr, 0, BAD_CAST "updateRequest", 0);
1289 ns_ucp = xmlNewNs(ptr, BAD_CAST ns_ucp_str, BAD_CAST "zu");
1290 xmlSetNs(ptr, ns_ucp);
1291 ns_srw = xmlNewNs(ptr, BAD_CAST ns_srw_str, BAD_CAST "zs");
1292
1293 add_xsd_string_ns(ptr, "version", (*p)->srw_version, ns_srw);
1294 add_xsd_string(ptr, "action", req->operation);
1295 add_xsd_string(ptr, "recordIdentifier", req->recordId );
1296 if (req->recordVersions)
1297 yaz_srw_versions( o, ptr, &req->recordVersions,
1298 &req->num_recordVersions,
1299 client_data, ns_ucp_str);
1300 if (req->record && req->record->recordData_len)
1301 {
1302 xmlNodePtr rptr = xmlNewChild(ptr, 0, BAD_CAST "record", 0);
1303 xmlSetNs(rptr, ns_srw);
1304 yaz_srw_record(o, rptr, req->record, &req->extra_record,
1305 client_data, 0);
1306 }
1307 if (req->extraRequestData_len)
1308 {
1309 add_XML_n(ptr, "extraRequestData",
1311 req->extraRequestData_len, ns_srw);
1312 }
1313 add_xsd_string(ptr, "stylesheet", req->stylesheet);
1314 add_xsd_string(ptr, "database", req->database);
1315 }
1316 else if ((*p)->which == Z_SRW_update_response)
1317 {
1318 Z_SRW_updateResponse *res = (*p)->u.update_response;
1319 xmlNodePtr ptr = xmlNewChild(pptr, 0, (xmlChar *)
1320 "updateResponse", 0);
1321 ns_ucp = xmlNewNs(ptr, BAD_CAST ns_ucp_str, BAD_CAST "zu");
1322 xmlSetNs(ptr, ns_ucp);
1323 ns_srw = xmlNewNs(ptr, BAD_CAST ns_srw_str, BAD_CAST "zs");
1324
1325 add_xsd_string_ns(ptr, "version", (*p)->srw_version, ns_srw);
1326 add_xsd_string(ptr, "operationStatus", res->operationStatus );
1327 add_xsd_string(ptr, "recordIdentifier", res->recordId );
1328 if (res->recordVersions)
1329 yaz_srw_versions(o, ptr, &res->recordVersions,
1330 &res->num_recordVersions,
1331 client_data, ns_ucp_str);
1332 if (res->record && res->record->recordData_len)
1333 {
1334 xmlNodePtr rptr = xmlNewChild(ptr, 0, BAD_CAST "record", 0);
1335 xmlSetNs(rptr, ns_srw);
1336 yaz_srw_record(o, rptr, res->record, &res->extra_record,
1337 client_data, 0);
1338 }
1339 if (res->num_diagnostics)
1340 {
1341 xmlNsPtr ns_diag =
1342 xmlNewNs(pptr, BAD_CAST YAZ_XMLNS_DIAG_v1_1,
1343 BAD_CAST "diag" );
1344
1345 xmlNodePtr rptr = xmlNewChild(ptr, ns_diag, BAD_CAST "diagnostics", 0);
1346 yaz_srw_diagnostics(o, rptr, &res->diagnostics,
1347 &res->num_diagnostics, client_data,
1348 ns_ucp_str, 0);
1349 }
1350 if (res->extraResponseData_len)
1351 add_XML_n(ptr, "extraResponseData",
1353 res->extraResponseData_len, ns_srw);
1354 }
1355 else
1356 return -1;
1357 }
1358 return 0;
1359}
1360
1361#endif
1362
1363
1364/*
1365 * Local variables:
1366 * c-basic-offset: 4
1367 * c-file-style: "Stroustrup"
1368 * indent-tabs-mode: nil
1369 * End:
1370 * vim: shiftwidth=4 tabstop=8 expandtab
1371 */
1372
const char * yaz_diag_sru_update_str(int code)
const char * yaz_diag_srw_str(int code)
Definition diagsrw.c:110
Z_FacetList * facet_list_create(ODR odr, int num_facets)
Definition facet.c:215
Z_FacetTerm * facet_term_create_cstr(ODR odr, const char *cstr, Odr_int freq)
Definition facet.c:189
void facet_field_term_set(ODR odr, Z_FacetField *field, Z_FacetTerm *facet_term, int index)
Definition facet.c:208
void facet_list_field_set(ODR odr, Z_FacetList *list, Z_FacetField *field, int index)
Definition facet.c:224
Z_FacetField * facet_field_create(ODR odr, Z_AttributeList *attributes, int num_terms)
Definition facet.c:198
Header for the facet utilities.
char * name
Definition initopt.c:18
void yaz_log(int level, const char *fmt,...)
Writes log message.
Definition log.c:487
#define YLOG_DEBUG
log level: debugging
Definition log.h:44
Header for Nibble Memory functions + Libxml2 specific stuff.
char * nmem_text_node_cdata(const xmlNode *ptr_cdata, NMEM nmem)
copies TEXT Libxml2 node data to NMEM
Definition nmemsdup.c:145
#define ODR_DECODE
Definition odr.h:95
#define odr_getmem(o)
Definition odr.h:216
nmem_int_t Odr_int
Definition odr.h:47
#define ODR_ENCODE
Definition odr.h:96
void * odr_malloc(ODR o, size_t size)
Definition odr_mem.c:31
Odr_int odr_atoi(const char *s)
Definition odr_mem.c:146
Z_AttributeList * zget_AttributeList_use_string(ODR o, const char *name)
creates AttributeList with type=1(use) and string value
Definition pquery.c:310
Header for Z39.50 Protocol.
SRU private header.
int yaz_match_xsd_element(xmlNodePtr ptr, const char *elem)
Definition xml_match.c:17
xmlNodePtr add_xsd_string_ns(xmlNodePtr ptr, const char *elem, const char *val, xmlNsPtr ns_ptr)
Definition xml_add.c:48
const char * yaz_element_attribute_value_get(xmlNodePtr ptr, const char *node_name, const char *attribute_name)
Definition srwutil.c:71
int yaz_match_xsd_XML_n2(xmlNodePtr ptr, const char *elem, ODR o, char **val, int *len, int fixup_root)
Definition xml_match.c:76
void add_XML_n(xmlNodePtr ptr, const char *elem, char *val, int len, xmlNsPtr ns_ptr)
Definition xml_add.c:19
void add_xsd_integer(xmlNodePtr ptr, const char *elem, const Odr_int *val)
Definition xml_add.c:66
xmlNodePtr add_xsd_string(xmlNodePtr ptr, const char *elem, const char *val)
Definition xml_add.c:61
void yaz_sru_facet_request(ODR, Z_FacetList **facetList, const char **limit, const char **start, const char **sort)
Definition sru_facet.c:60
int yaz_match_xsd_XML_n(xmlNodePtr ptr, const char *elem, ODR o, char **val, int *len)
Definition xml_match.c:120
int yaz_match_xsd_string_n(xmlNodePtr ptr, const char *elem, ODR o, char **val, int *len)
Definition xml_match.c:65
void yaz_sru_facet_response(ODR o, Z_FacetList **facetList, xmlNodePtr n)
Definition sru_facet.c:189
int yaz_match_xsd_string(xmlNodePtr ptr, const char *elem, ODR o, char **val)
Definition xml_match.c:71
xmlNodePtr add_xsd_string_n(xmlNodePtr ptr, const char *elem, const char *val, int len)
Definition xml_add.c:35
int yaz_match_xsd_integer(xmlNodePtr ptr, const char *elem, ODR o, Odr_int **val)
Definition xml_match.c:126
int sru_decode_surrogate_diagnostics(const char *buf, size_t len, Z_SRW_diagnostic **diag, int *num, ODR odr)
Definition srw.c:411
static void encode_echoed_args(xmlNodePtr ptr, Z_SRW_PDU *p, const char *name)
Definition srw.c:551
Z_FacetTerm * yaz_sru_proxy_get_facet_term_count(ODR odr, xmlNodePtr node)
Definition srw.c:278
static int yaz_srw_version(ODR o, xmlNodePtr pptr, Z_SRW_recordVersion *rec, void *client_data, const char *ns)
Definition srw.c:209
char * yaz_negotiate_sru_version(char *input_ver)
Definition srw.c:26
static int yaz_srw_diagnostics(ODR o, xmlNodePtr pptr, Z_SRW_diagnostic **recs, int *num, void *client_data, const char *ns, int version2)
Definition srw.c:433
int yaz_ucp_codec(ODR o, void *vptr, Z_SRW_PDU **handler_data, void *client_data, const char *ns_ucp_str)
Definition srw.c:1144
static int yaz_srw_records(ODR o, xmlNodePtr pptr, Z_SRW_record **recs, Z_SRW_extra_record ***extra, int *num, void *client_data, int version2)
Definition srw.c:166
static Z_FacetField * yaz_sru_proxy_decode_facet_field(ODR odr, xmlNodePtr ptr)
Definition srw.c:294
static int yaz_srw_decode_diagnostics(ODR o, xmlNodePtr pptr, Z_SRW_diagnostic **recs, int *num, void *client_data, const char *ns)
Definition srw.c:363
static int yaz_srw_versions(ODR o, xmlNodePtr pptr, Z_SRW_recordVersion **vers, int *num, void *client_data, const char *ns)
Definition srw.c:237
static int yaz_srw_terms(ODR o, xmlNodePtr pptr, Z_SRW_scanTerm **terms, int *num, void *client_data, const char *ns)
Definition srw.c:515
static int yaz_srw_term(ODR o, xmlNodePtr pptr, Z_SRW_scanTerm *term, void *client_data, const char *ns)
Definition srw.c:480
static int yaz_sru_proxy_decode_facets(ODR o, xmlNodePtr root, Z_FacetList **facetList)
Definition srw.c:325
int yaz_srw_codec(ODR o, void *vptr, Z_SRW_PDU **handler_data, void *client_data, const char *ns)
Definition srw.c:575
static int yaz_srw_record(ODR o, xmlNodePtr pptr, Z_SRW_record *rec, Z_SRW_extra_record **extra, void *client_data, int version2)
Definition srw.c:39
Header for SRW/SRU.
#define Z_SRW_recordPacking_XML
Definition srw.h:55
#define Z_SRW_searchRetrieve_response
Definition srw.h:192
#define Z_SRW_explain_request
Definition srw.h:193
#define Z_SRW_update_request
Definition srw.h:197
#define Z_SRW_scan_request
Definition srw.h:195
#define YAZ_XMLNS_DIAG_v1_1
Definition srw.h:329
#define YAZ_XMLNS_SRU_v1_1
Definition srw.h:328
#define Z_SRW_sort_type_none
Definition srw.h:74
#define Z_SRW_recordPacking_string
Definition srw.h:54
#define Z_SRW_recordPacking_URL
Definition srw.h:56
#define Z_SRW_update_response
Definition srw.h:198
#define YAZ_XMLNS_DIAG_v2
Definition srw.h:330
#define Z_SRW_sort_type_sort
Definition srw.h:75
#define Z_SRW_explain_response
Definition srw.h:194
#define Z_SRW_scan_response
Definition srw.h:196
#define Z_SRW_sort_type_xSort
Definition srw.h:76
#define Z_SRW_searchRetrieve_request
Definition srw.h:191
Z_SRW_record * yaz_srw_get_record(ODR o)
Definition srwutil.c:733
const char * yaz_srw_pack_to_str(int pack)
Definition srwutil.c:1210
Z_SRW_PDU * yaz_srw_get_core_v_2_0(ODR o)
Definition srwutil.c:750
char * srw_version
Definition srw.h:212
Z_SRW_extra_arg * extra_args
Definition srw.h:219
char * uri
Definition srw.h:64
char * database
Definition srw.h:118
char * stylesheet
Definition srw.h:119
char * recordPacking
Definition srw.h:116
Z_SRW_diagnostic * diagnostics
Definition srw.h:124
Z_SRW_record record
Definition srw.h:123
Z_SRW_extra_record * extra_record
Definition srw.h:126
char * value
Definition srw.h:174
Z_SRW_extra_arg * next
Definition srw.h:175
char * name
Definition srw.h:173
int extraRecordData_len
Definition srw.h:46
char * extraRecordData_buf
Definition srw.h:45
char * recordIdentifier
Definition srw.h:47
char * versionValue
Definition srw.h:155
char * versionType
Definition srw.h:154
char * recordData_buf
Definition srw.h:58
int recordPacking
Definition srw.h:53
char * recordSchema
Definition srw.h:51
int recordData_len
Definition srw.h:59
Odr_int * recordPosition
Definition srw.h:60
Odr_int * responsePosition
Definition srw.h:132
Odr_int * maximumTerms
Definition srw.h:133
char * queryType
Definition srw.h:130
char * scanClause
Definition srw.h:131
char * stylesheet
Definition srw.h:134
char * database
Definition srw.h:135
Z_SRW_diagnostic * diagnostics
Definition srw.h:148
Z_SRW_scanTerm * terms
Definition srw.h:146
int num_diagnostics
Definition srw.h:149
char * displayTerm
Definition srw.h:141
char * whereInList
Definition srw.h:142
Odr_int * numberOfRecords
Definition srw.h:140
char * value
Definition srw.h:139
Odr_int * resultSetTTL
Definition srw.h:93
Z_FacetList * facetList
Definition srw.h:94
Odr_int * maximumRecords
Definition srw.h:84
Odr_int * startRecord
Definition srw.h:83
union Z_SRW_searchRetrieveRequest::@29 sort
Z_SRW_record * records
Definition srw.h:103
Odr_int * numberOfRecords
Definition srw.h:98
Z_SRW_diagnostic * diagnostics
Definition srw.h:106
Odr_int * nextRecordPosition
Definition srw.h:108
Odr_int * resultSetIdleTime
Definition srw.h:101
Z_SRW_extra_record ** extra_records
Definition srw.h:110
Z_FacetList * facetList
Definition srw.h:111
char * database
Definition srw.h:159
int extraRequestData_len
Definition srw.h:167
char * operation
Definition srw.h:160
char * stylesheet
Definition srw.h:168
char * recordId
Definition srw.h:161
Z_SRW_extra_record * extra_record
Definition srw.h:165
Z_SRW_recordVersion * recordVersions
Definition srw.h:162
int num_recordVersions
Definition srw.h:163
Z_SRW_record * record
Definition srw.h:164
char * extraRequestData_buf
Definition srw.h:166
char * operationStatus
Definition srw.h:179
char * recordId
Definition srw.h:180
Z_SRW_diagnostic * diagnostics
Definition srw.h:187
Z_SRW_record * record
Definition srw.h:183
int extraResponseData_len
Definition srw.h:186
int num_recordVersions
Definition srw.h:182
Z_SRW_recordVersion * recordVersions
Definition srw.h:181
char * extraResponseData_buf
Definition srw.h:185
Z_SRW_extra_record * extra_record
Definition srw.h:184
Definition odr.h:125
int direction
Definition odr.h:126
Header for WRBUF (growing buffer)