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