2 * Copyright (C) 1995-2006, Index Data ApS
3 * See the file LICENSE for details.
5 * $Id: srw.c,v 1.51 2006-11-30 22:58:06 adam Exp $
9 * \brief Implements SRW/SRU package encoding and decoding
14 #include <libxml/parser.h>
15 #include <libxml/tree.h>
18 static void add_XML_n(xmlNodePtr ptr, const char *elem, char *val, int len)
22 xmlDocPtr doc = xmlParseMemory(val,len);
25 xmlNodePtr c = xmlNewChild(ptr, 0, BAD_CAST elem, 0);
26 xmlNodePtr t = xmlDocGetRootElement(doc);
27 xmlAddChild(c, xmlCopyNode(t,1));
33 xmlNodePtr add_xsd_string_n(xmlNodePtr ptr, const char *elem, const char *val,
38 xmlNodePtr c = xmlNewChild(ptr, 0, BAD_CAST elem, 0);
39 xmlNodePtr t = xmlNewTextLen(BAD_CAST val, len);
46 xmlNodePtr add_xsd_string(xmlNodePtr ptr, const char *elem, const char *val)
49 return xmlNewTextChild(ptr, 0, BAD_CAST elem,
54 static void add_xsd_integer(xmlNodePtr ptr, const char *elem, const int *val)
59 sprintf(str, "%d", *val);
60 xmlNewTextChild(ptr, 0, BAD_CAST elem, BAD_CAST str);
64 static int match_element(xmlNodePtr ptr, const char *elem)
66 if (ptr->type == XML_ELEMENT_NODE && !xmlStrcmp(ptr->name, BAD_CAST elem))
73 static int match_xsd_string_n(xmlNodePtr ptr, const char *elem, ODR o,
77 struct _xmlAttr *attr;
79 if (!match_element(ptr, elem))
82 for (attr = ptr->properties; attr; attr = attr->next)
83 if (!strcmp(attr->name, "type") &&
84 attr->children && attr->children->type == XML_TEXT_NODE)
86 const char *t = strchr(attr->children->content, ':');
90 t = attr->children->content;
91 if (!strcmp(t, "string"))
98 if (!ptr || ptr->type != XML_TEXT_NODE)
103 *val = odr_strdup(o, (const char *) ptr->content);
105 *len = xmlStrlen(ptr->content);
110 static int match_xsd_string(xmlNodePtr ptr, const char *elem, ODR o,
113 return match_xsd_string_n(ptr, elem, o, val, 0);
117 /** \brief fixes NS for root node of record data (bug #740) */
118 static void fixup_xmlns(xmlNodePtr ptr, ODR o)
120 /* should go towards root and collect NS not defined in the record here! */
125 assert(p->type == XML_ELEMENT_NODE);
128 while (p && p->type != XML_ELEMENT_NODE)
133 for (; ns; ns = ns->next)
136 for (n = ptr->nsDef; n; n = n->next)
137 if ((n->prefix == 0 && ns->prefix == 0)
138 || (n->prefix && ns->prefix
139 && !strcmp((const char *) n->prefix,
140 (const char *) ns->prefix)))
146 xmlNsPtr new_ns = xmlCopyNamespace(ns);
148 new_ns->next = ptr->nsDef;
156 static int match_xsd_XML_n(xmlNodePtr ptr, const char *elem, ODR o,
157 char **val, int *len)
161 if (!match_element(ptr, elem))
165 while (ptr && (ptr->type == XML_TEXT_NODE || ptr->type == XML_COMMENT_NODE))
172 buf = xmlBufferCreate();
174 xmlNodeDump(buf, ptr->doc, ptr, 0, 0);
176 *val = odr_malloc(o, buf->use+1);
177 memcpy (*val, buf->content, buf->use);
178 (*val)[buf->use] = '\0';
188 static int match_xsd_integer(xmlNodePtr ptr, const char *elem, ODR o, int **val)
191 struct _xmlAttr *attr;
193 if (!match_element(ptr, elem))
196 for (attr = ptr->properties; attr; attr = attr->next)
197 if (!strcmp(attr->name, "type") &&
198 attr->children && attr->children->type == XML_TEXT_NODE)
200 const char *t = strchr(attr->children->content, ':');
204 t = attr->children->content;
205 if (!strcmp(t, "integer"))
212 if (!ptr || ptr->type != XML_TEXT_NODE)
214 *val = odr_intdup(o, atoi((const char *) ptr->content));
218 static int yaz_srw_extra_record(ODR o, xmlNodePtr pptr,
219 Z_SRW_extra_record *rec,
220 void *client_data, const char *ns)
222 if (o->direction == ODR_DECODE)
227 rec->recordReviewCode = 0;
228 rec->recordReviewNote = 0;
229 rec->recordLockStatus = 0;
230 rec->recordOldVersion = 0;
231 rec->nonDupRecordId = 0;
232 for (ptr = pptr->children; ptr; ptr = ptr->next)
234 if (match_xsd_string(ptr, "recordId", o,
236 ; /* backward compatible */
237 else if (match_xsd_string(ptr, "recordIdentifier", o,
240 else if (match_xsd_string(ptr, "recordReviewCode", o,
241 &rec->recordReviewCode ))
243 else if (match_xsd_string(ptr, "recordReviewNote", o,
244 &rec->recordReviewNote ))
246 else if (match_xsd_string(ptr, "nonDupRecordId", o,
247 &rec->nonDupRecordId ))
249 else if (match_xsd_string(ptr, "recordLockStatus", o,
250 &rec->recordLockStatus ))
252 else if (match_xsd_string(ptr, "recordOldVersion", o,
253 &rec->recordOldVersion ))
257 else if (o->direction == ODR_ENCODE)
259 xmlNodePtr ptr = pptr;
261 add_xsd_string(ptr, "recordIdentfier", rec->recordId);
262 if ( rec->recordReviewCode )
263 add_xsd_string(ptr, "recordReviewCode", rec->recordReviewCode);
264 if ( rec->recordReviewNote )
265 add_xsd_string(ptr, "recordReviewNote", rec->recordReviewNote);
266 if ( rec->nonDupRecordId )
267 add_xsd_string(ptr, "nonDupRecordId", rec->nonDupRecordId);
268 if ( rec->recordLockStatus )
269 add_xsd_string(ptr, "recordLockStatus", rec->recordLockStatus);
270 if ( rec->recordOldVersion )
271 add_xsd_string(ptr, "recordOldVersion", rec->recordOldVersion);
276 static int yaz_srw_record(ODR o, xmlNodePtr pptr, Z_SRW_record *rec,
277 Z_SRW_extra_record **extra,
278 void *client_data, const char *ns)
280 if (o->direction == ODR_DECODE)
283 int pack = Z_SRW_recordPacking_string;
285 xmlNodePtr data_ptr = 0;
286 rec->recordSchema = 0;
287 rec->recordData_buf = 0;
288 rec->recordData_len = 0;
289 rec->recordPosition = 0;
291 for (ptr = pptr->children; ptr; ptr = ptr->next)
294 if (match_xsd_string(ptr, "recordSchema", o,
297 else if (match_xsd_string(ptr, "recordPacking", o, &spack))
299 if (spack && !strcmp(spack, "xml"))
300 pack = Z_SRW_recordPacking_XML;
301 if (spack && !strcmp(spack, "url"))
302 pack = Z_SRW_recordPacking_URL;
303 if (spack && !strcmp(spack, "string"))
304 pack = Z_SRW_recordPacking_string;
306 else if (match_xsd_integer(ptr, "recordPosition", o,
307 &rec->recordPosition))
309 else if (match_element(ptr, "recordData"))
311 /* save position of Data until after the loop
312 then we will know the packing (hopefully), and
313 unpacking is done once
317 else if (match_element(ptr, "extraRecordData"))
319 *extra = (Z_SRW_extra_record *)
320 odr_malloc(o, sizeof(Z_SRW_extra_record));
321 yaz_srw_extra_record(o, ptr, *extra, client_data, ns);
328 case Z_SRW_recordPacking_XML:
329 match_xsd_XML_n(data_ptr, "recordData", o,
330 &rec->recordData_buf, &rec->recordData_len);
332 case Z_SRW_recordPacking_URL:
333 /* just store it as a string.
334 leave it to the backend to collect the document */
335 match_xsd_string_n(data_ptr, "recordData", o,
336 &rec->recordData_buf, &rec->recordData_len);
338 case Z_SRW_recordPacking_string:
339 match_xsd_string_n(data_ptr, "recordData", o,
340 &rec->recordData_buf, &rec->recordData_len);
344 rec->recordPacking = pack;
346 else if (o->direction == ODR_ENCODE)
348 xmlNodePtr ptr = pptr;
349 int pack = rec->recordPacking;
350 add_xsd_string(ptr, "recordSchema", rec->recordSchema);
354 case Z_SRW_recordPacking_string:
355 add_xsd_string(ptr, "recordPacking", "string");
356 add_xsd_string_n(ptr, "recordData", rec->recordData_buf,
357 rec->recordData_len);
359 case Z_SRW_recordPacking_XML:
360 add_xsd_string(ptr, "recordPacking", "xml");
361 add_XML_n(ptr, "recordData", rec->recordData_buf,
362 rec->recordData_len);
364 case Z_SRW_recordPacking_URL:
365 add_xsd_string(ptr, "recordPacking", "url");
366 add_xsd_string_n(ptr, "recordData", rec->recordData_buf,
367 rec->recordData_len);
370 if (rec->recordPosition)
371 add_xsd_integer(ptr, "recordPosition", rec->recordPosition );
374 xmlNodePtr rptr = xmlNewChild(ptr, 0, BAD_CAST "extraRecordData",
376 yaz_srw_extra_record(o, rptr, *extra, client_data, ns);
382 static int yaz_srw_records(ODR o, xmlNodePtr pptr, Z_SRW_record **recs,
383 Z_SRW_extra_record ***extra,
384 int *num, void *client_data, const char *ns)
386 if (o->direction == ODR_DECODE)
391 for (ptr = pptr->children; ptr; ptr = ptr->next)
393 if (ptr->type == XML_ELEMENT_NODE &&
394 !xmlStrcmp(ptr->name, BAD_CAST "record"))
399 *recs = (Z_SRW_record *) odr_malloc(o, *num * sizeof(**recs));
400 *extra = (Z_SRW_extra_record **) odr_malloc(o, *num * sizeof(**extra));
401 for (i = 0, ptr = pptr->children; ptr; ptr = ptr->next)
403 if (ptr->type == XML_ELEMENT_NODE &&
404 !xmlStrcmp(ptr->name, BAD_CAST "record"))
406 yaz_srw_record(o, ptr, *recs + i, *extra + i, client_data, ns);
411 else if (o->direction == ODR_ENCODE)
414 for (i = 0; i < *num; i++)
416 xmlNodePtr rptr = xmlNewChild(pptr, 0, BAD_CAST "record",
418 yaz_srw_record(o, rptr, (*recs)+i, (*extra ? *extra + i : 0),
425 static int yaz_srw_diagnostics(ODR o, xmlNodePtr pptr, Z_SRW_diagnostic **recs,
426 int *num, void *client_data, const char *ns)
428 if (o->direction == ODR_DECODE)
433 for (ptr = pptr->children; ptr; ptr = ptr->next)
435 if (ptr->type == XML_ELEMENT_NODE &&
436 !xmlStrcmp(ptr->name, BAD_CAST "diagnostic"))
441 *recs = (Z_SRW_diagnostic *) odr_malloc(o, *num * sizeof(**recs));
442 for (i = 0; i < *num; i++)
445 (*recs)[i].details = 0;
446 (*recs)[i].message = 0;
448 for (i = 0, ptr = pptr->children; ptr; ptr = ptr->next)
450 if (ptr->type == XML_ELEMENT_NODE &&
451 !xmlStrcmp(ptr->name, BAD_CAST "diagnostic"))
455 (*recs)[i].details = 0;
456 (*recs)[i].message = 0;
457 for (rptr = ptr->children; rptr; rptr = rptr->next)
459 if (match_xsd_string(rptr, "uri", o,
462 else if (match_xsd_string(rptr, "details", o,
463 &(*recs)[i].details))
465 else if (match_xsd_string(rptr, "message", o,
466 &(*recs)[i].message))
473 else if (o->direction == ODR_ENCODE)
477 xmlNewNs(pptr, BAD_CAST
478 "http://www.loc.gov/zing/srw/diagnostic/", 0);
479 for (i = 0; i < *num; i++)
481 const char *std_diag = "info:srw/diagnostic/1/";
482 const char *ucp_diag = "info:srw/diagnostic/12/";
483 xmlNodePtr rptr = xmlNewChild(pptr, ns_diag,
484 BAD_CAST "diagnostic", 0);
485 add_xsd_string(rptr, "uri", (*recs)[i].uri);
486 if ((*recs)[i].message)
487 add_xsd_string(rptr, "message", (*recs)[i].message);
488 else if ((*recs)[i].uri )
490 if (!strncmp((*recs)[i].uri, std_diag, strlen(std_diag)))
492 int no = atoi((*recs)[i].uri + strlen(std_diag));
493 const char *message = yaz_diag_srw_str(no);
495 add_xsd_string(rptr, "message", message);
497 else if (!strncmp((*recs)[i].uri, ucp_diag, strlen(ucp_diag)))
499 int no = atoi((*recs)[i].uri + strlen(ucp_diag));
500 const char *message = yaz_diag_sru_update_str(no);
502 add_xsd_string(rptr, "message", message);
505 add_xsd_string(rptr, "details", (*recs)[i].details);
511 static int yaz_srw_term(ODR o, xmlNodePtr pptr, Z_SRW_scanTerm *term,
512 void *client_data, const char *ns)
514 if (o->direction == ODR_DECODE)
518 term->numberOfRecords = 0;
519 term->displayTerm = 0;
520 term->whereInList = 0;
521 for (ptr = pptr->children; ptr; ptr = ptr->next)
523 if (match_xsd_string(ptr, "value", o, &term->value))
525 else if (match_xsd_integer(ptr, "numberOfRecords", o,
526 &term->numberOfRecords))
528 else if (match_xsd_string(ptr, "displayTerm", o,
531 else if (match_xsd_string(ptr, "whereInList", o,
536 else if (o->direction == ODR_ENCODE)
538 xmlNodePtr ptr = pptr;
539 add_xsd_string(ptr, "value", term->value);
540 add_xsd_integer(ptr, "numberOfRecords", term->numberOfRecords);
541 add_xsd_string(ptr, "displayTerm", term->displayTerm);
542 add_xsd_string(ptr, "whereInList", term->whereInList);
547 static int yaz_srw_terms(ODR o, xmlNodePtr pptr, Z_SRW_scanTerm **terms,
548 int *num, void *client_data, const char *ns)
550 if (o->direction == ODR_DECODE)
555 for (ptr = pptr->children; ptr; ptr = ptr->next)
557 if (ptr->type == XML_ELEMENT_NODE &&
558 !xmlStrcmp(ptr->name, BAD_CAST "term"))
563 *terms = (Z_SRW_scanTerm *) odr_malloc(o, *num * sizeof(**terms));
564 for (i = 0, ptr = pptr->children; ptr; ptr = ptr->next, i++)
566 if (ptr->type == XML_ELEMENT_NODE &&
567 !xmlStrcmp(ptr->name, BAD_CAST "term"))
568 yaz_srw_term(o, ptr, (*terms)+i, client_data, ns);
571 else if (o->direction == ODR_ENCODE)
574 for (i = 0; i < *num; i++)
576 xmlNodePtr rptr = xmlNewChild(pptr, 0, BAD_CAST "term", 0);
577 yaz_srw_term(o, rptr, (*terms)+i, client_data, ns);
583 int yaz_srw_codec(ODR o, void * vptr, Z_SRW_PDU **handler_data,
584 void *client_data, const char *ns)
586 xmlNodePtr pptr = (xmlNodePtr) vptr;
587 if (o->direction == ODR_DECODE)
589 Z_SRW_PDU **p = handler_data;
590 xmlNodePtr method = pptr->children;
592 while (method && method->type == XML_TEXT_NODE)
593 method = method->next;
597 if (method->type != XML_ELEMENT_NODE)
600 *p = yaz_srw_get_core_v_1_1(o);
602 if (!xmlStrcmp(method->name, BAD_CAST "searchRetrieveRequest"))
604 xmlNodePtr ptr = method->children;
605 Z_SRW_searchRetrieveRequest *req;
607 (*p)->which = Z_SRW_searchRetrieve_request;
608 req = (*p)->u.request = (Z_SRW_searchRetrieveRequest *)
609 odr_malloc(o, sizeof(*req));
610 req->query_type = Z_SRW_query_type_cql;
612 req->sort_type = Z_SRW_sort_type_none;
614 req->startRecord = 0;
615 req->maximumRecords = 0;
616 req->recordSchema = 0;
617 req->recordPacking = 0;
618 req->recordXPath = 0;
619 req->resultSetTTL = 0;
623 for (; ptr; ptr = ptr->next)
625 if (match_xsd_string(ptr, "version", o,
628 else if (match_xsd_string(ptr, "query", o,
630 req->query_type = Z_SRW_query_type_cql;
631 else if (match_xsd_string(ptr, "pQuery", o,
633 req->query_type = Z_SRW_query_type_pqf;
634 else if (match_xsd_string(ptr, "xQuery", o,
636 req->query_type = Z_SRW_query_type_xcql;
637 else if (match_xsd_integer(ptr, "startRecord", o,
640 else if (match_xsd_integer(ptr, "maximumRecords", o,
641 &req->maximumRecords))
643 else if (match_xsd_string(ptr, "recordPacking", o,
644 &req->recordPacking))
646 else if (match_xsd_string(ptr, "recordSchema", o,
649 else if (match_xsd_string(ptr, "recordXPath", o,
652 else if (match_xsd_integer(ptr, "resultSetTTL", o,
655 else if (match_xsd_string(ptr, "sortKeys", o,
656 &req->sort.sortKeys))
657 req->sort_type = Z_SRW_sort_type_sort;
658 else if (match_xsd_string(ptr, "stylesheet", o,
661 else if (match_xsd_string(ptr, "database", o,
665 if (!req->query.cql && !req->query.pqf && !req->query.xcql)
667 /* should put proper diagnostic here */
671 else if (!xmlStrcmp(method->name, BAD_CAST "searchRetrieveResponse"))
673 xmlNodePtr ptr = method->children;
674 Z_SRW_searchRetrieveResponse *res;
676 (*p)->which = Z_SRW_searchRetrieve_response;
677 res = (*p)->u.response = (Z_SRW_searchRetrieveResponse *)
678 odr_malloc(o, sizeof(*res));
680 res->numberOfRecords = 0;
681 res->resultSetId = 0;
682 res->resultSetIdleTime = 0;
684 res->num_records = 0;
685 res->diagnostics = 0;
686 res->num_diagnostics = 0;
687 res->nextRecordPosition = 0;
689 for (; ptr; ptr = ptr->next)
691 if (match_xsd_string(ptr, "version", o,
694 else if (match_xsd_integer(ptr, "numberOfRecords", o,
695 &res->numberOfRecords))
697 else if (match_xsd_string(ptr, "resultSetId", o,
700 else if (match_xsd_integer(ptr, "resultSetIdleTime", o,
701 &res->resultSetIdleTime))
703 else if (match_element(ptr, "records"))
704 yaz_srw_records(o, ptr, &res->records,
706 &res->num_records, client_data, ns);
707 else if (match_xsd_integer(ptr, "nextRecordPosition", o,
708 &res->nextRecordPosition))
710 else if (match_element(ptr, "diagnostics"))
711 yaz_srw_diagnostics(o, ptr, &res->diagnostics,
712 &res->num_diagnostics,
716 else if (!xmlStrcmp(method->name, BAD_CAST "explainRequest"))
718 Z_SRW_explainRequest *req;
719 xmlNodePtr ptr = method->children;
721 (*p)->which = Z_SRW_explain_request;
722 req = (*p)->u.explain_request = (Z_SRW_explainRequest *)
723 odr_malloc(o, sizeof(*req));
724 req->recordPacking = 0;
727 for (; ptr; ptr = ptr->next)
729 if (match_xsd_string(ptr, "version", o,
732 else if (match_xsd_string(ptr, "stylesheet", o,
735 else if (match_xsd_string(ptr, "recordPacking", o,
736 &req->recordPacking))
738 else if (match_xsd_string(ptr, "database", o,
743 else if (!xmlStrcmp(method->name, BAD_CAST "explainResponse"))
745 Z_SRW_explainResponse *res;
746 xmlNodePtr ptr = method->children;
748 (*p)->which = Z_SRW_explain_response;
749 res = (*p)->u.explain_response = (Z_SRW_explainResponse*)
750 odr_malloc(o, sizeof(*res));
751 res->diagnostics = 0;
752 res->num_diagnostics = 0;
753 res->record.recordSchema = 0;
754 res->record.recordData_buf = 0;
755 res->record.recordData_len = 0;
756 res->record.recordPosition = 0;
758 for (; ptr; ptr = ptr->next)
760 if (match_xsd_string(ptr, "version", o,
763 else if (match_element(ptr, "record"))
764 yaz_srw_record(o, ptr, &res->record, &res->extra_record,
766 else if (match_element(ptr, "diagnostics"))
767 yaz_srw_diagnostics(o, ptr, &res->diagnostics,
768 &res->num_diagnostics,
773 else if (!xmlStrcmp(method->name, BAD_CAST "scanRequest"))
775 Z_SRW_scanRequest *req;
776 xmlNodePtr ptr = method->children;
778 (*p)->which = Z_SRW_scan_request;
779 req = (*p)->u.scan_request = (Z_SRW_scanRequest *)
780 odr_malloc(o, sizeof(*req));
781 req->query_type = Z_SRW_query_type_cql;
782 req->scanClause.cql = 0;
783 req->responsePosition = 0;
784 req->maximumTerms = 0;
788 for (; ptr; ptr = ptr->next)
790 if (match_xsd_string(ptr, "version", o,
793 else if (match_xsd_string(ptr, "scanClause", o,
794 &req->scanClause.cql))
796 else if (match_xsd_string(ptr, "pScanClause", o,
797 &req->scanClause.pqf))
799 req->query_type = Z_SRW_query_type_pqf;
801 else if (match_xsd_integer(ptr, "responsePosition", o,
802 &req->responsePosition))
804 else if (match_xsd_integer(ptr, "maximumTerms", o,
807 else if (match_xsd_string(ptr, "stylesheet", o,
810 else if (match_xsd_string(ptr, "database", o,
815 else if (!xmlStrcmp(method->name, BAD_CAST "scanResponse"))
817 Z_SRW_scanResponse *res;
818 xmlNodePtr ptr = method->children;
820 (*p)->which = Z_SRW_scan_response;
821 res = (*p)->u.scan_response = (Z_SRW_scanResponse *)
822 odr_malloc(o, sizeof(*res));
825 res->diagnostics = 0;
826 res->num_diagnostics = 0;
828 for (; ptr; ptr = ptr->next)
830 if (match_xsd_string(ptr, "version", o,
833 else if (match_element(ptr, "terms"))
834 yaz_srw_terms(o, ptr, &res->terms,
835 &res->num_terms, client_data,
837 else if (match_element(ptr, "diagnostics"))
838 yaz_srw_diagnostics(o, ptr, &res->diagnostics,
839 &res->num_diagnostics,
849 else if (o->direction == ODR_ENCODE)
851 Z_SRW_PDU **p = handler_data;
854 if ((*p)->which == Z_SRW_searchRetrieve_request)
856 Z_SRW_searchRetrieveRequest *req = (*p)->u.request;
857 xmlNodePtr ptr = xmlNewChild(pptr, 0,
858 BAD_CAST "searchRetrieveRequest", 0);
859 ns_srw = xmlNewNs(ptr, BAD_CAST ns, BAD_CAST "zs");
860 xmlSetNs(ptr, ns_srw);
862 if ((*p)->srw_version)
863 add_xsd_string(ptr, "version", (*p)->srw_version);
864 switch(req->query_type)
866 case Z_SRW_query_type_cql:
867 add_xsd_string(ptr, "query", req->query.cql);
869 case Z_SRW_query_type_xcql:
870 add_xsd_string(ptr, "xQuery", req->query.xcql);
872 case Z_SRW_query_type_pqf:
873 add_xsd_string(ptr, "pQuery", req->query.pqf);
876 add_xsd_integer(ptr, "startRecord", req->startRecord);
877 add_xsd_integer(ptr, "maximumRecords", req->maximumRecords);
878 add_xsd_string(ptr, "recordPacking", req->recordPacking);
879 add_xsd_string(ptr, "recordSchema", req->recordSchema);
880 add_xsd_string(ptr, "recordXPath", req->recordXPath);
881 add_xsd_integer(ptr, "resultSetTTL", req->resultSetTTL);
882 switch(req->sort_type)
884 case Z_SRW_sort_type_none:
886 case Z_SRW_sort_type_sort:
887 add_xsd_string(ptr, "sortKeys", req->sort.sortKeys);
889 case Z_SRW_sort_type_xSort:
890 add_xsd_string(ptr, "xSortKeys", req->sort.xSortKeys);
893 add_xsd_string(ptr, "stylesheet", req->stylesheet);
894 add_xsd_string(ptr, "database", req->database);
896 else if ((*p)->which == Z_SRW_searchRetrieve_response)
898 Z_SRW_searchRetrieveResponse *res = (*p)->u.response;
899 xmlNodePtr ptr = xmlNewChild(pptr, 0,
900 BAD_CAST "searchRetrieveResponse", 0);
901 ns_srw = xmlNewNs(ptr, BAD_CAST ns, BAD_CAST "zs");
902 xmlSetNs(ptr, ns_srw);
904 if ((*p)->srw_version)
905 add_xsd_string(ptr, "version", (*p)->srw_version);
906 add_xsd_integer(ptr, "numberOfRecords", res->numberOfRecords);
907 add_xsd_string(ptr, "resultSetId", res->resultSetId);
908 add_xsd_integer(ptr, "resultSetIdleTime", res->resultSetIdleTime);
909 if (res->num_records)
911 xmlNodePtr rptr = xmlNewChild(ptr, 0, BAD_CAST "records", 0);
912 yaz_srw_records(o, rptr, &res->records, &res->extra_records,
916 add_xsd_integer(ptr, "nextRecordPosition",
917 res->nextRecordPosition);
918 if (res->num_diagnostics)
920 xmlNodePtr rptr = xmlNewChild(ptr, 0, BAD_CAST "diagnostics",
922 yaz_srw_diagnostics(o, rptr, &res->diagnostics,
923 &res->num_diagnostics, client_data, ns);
926 else if ((*p)->which == Z_SRW_explain_request)
928 Z_SRW_explainRequest *req = (*p)->u.explain_request;
929 xmlNodePtr ptr = xmlNewChild(pptr, 0, BAD_CAST "explainRequest",
931 ns_srw = xmlNewNs(ptr, BAD_CAST ns, BAD_CAST "zs");
932 xmlSetNs(ptr, ns_srw);
934 add_xsd_string(ptr, "version", (*p)->srw_version);
935 add_xsd_string(ptr, "recordPacking", req->recordPacking);
936 add_xsd_string(ptr, "stylesheet", req->stylesheet);
937 add_xsd_string(ptr, "database", req->database);
939 else if ((*p)->which == Z_SRW_explain_response)
941 Z_SRW_explainResponse *res = (*p)->u.explain_response;
942 xmlNodePtr ptr = xmlNewChild(pptr, 0, BAD_CAST "explainResponse",
944 ns_srw = xmlNewNs(ptr, BAD_CAST ns, BAD_CAST "zs");
945 xmlSetNs(ptr, ns_srw);
947 add_xsd_string(ptr, "version", (*p)->srw_version);
950 xmlNodePtr ptr1 = xmlNewChild(ptr, 0, BAD_CAST "record", 0);
951 yaz_srw_record(o, ptr1, &res->record, &res->extra_record,
954 if (res->num_diagnostics)
956 xmlNodePtr rptr = xmlNewChild(ptr, 0, BAD_CAST "diagnostics",
958 yaz_srw_diagnostics(o, rptr, &res->diagnostics,
959 &res->num_diagnostics, client_data, ns);
962 else if ((*p)->which == Z_SRW_scan_request)
964 Z_SRW_scanRequest *req = (*p)->u.scan_request;
965 xmlNodePtr ptr = xmlNewChild(pptr, 0, BAD_CAST "scanRequest", 0);
966 ns_srw = xmlNewNs(ptr, BAD_CAST ns, BAD_CAST "zs");
967 xmlSetNs(ptr, ns_srw);
969 add_xsd_string(ptr, "version", (*p)->srw_version);
970 switch(req->query_type)
972 case Z_SRW_query_type_cql:
973 add_xsd_string(ptr, "scanClause", req->scanClause.cql);
975 case Z_SRW_query_type_pqf:
976 add_xsd_string(ptr, "pScanClause", req->scanClause.pqf);
979 add_xsd_integer(ptr, "responsePosition", req->responsePosition);
980 add_xsd_integer(ptr, "maximumTerms", req->maximumTerms);
981 add_xsd_string(ptr, "stylesheet", req->stylesheet);
982 add_xsd_string(ptr, "database", req->database);
984 else if ((*p)->which == Z_SRW_scan_response)
986 Z_SRW_scanResponse *res = (*p)->u.scan_response;
987 xmlNodePtr ptr = xmlNewChild(pptr, 0, BAD_CAST "scanResponse", 0);
988 ns_srw = xmlNewNs(ptr, BAD_CAST ns, BAD_CAST "zs");
989 xmlSetNs(ptr, ns_srw);
991 add_xsd_string(ptr, "version", (*p)->srw_version);
995 xmlNodePtr rptr = xmlNewChild(ptr, 0, BAD_CAST "terms", 0);
996 yaz_srw_terms(o, rptr, &res->terms, &res->num_terms,
999 if (res->num_diagnostics)
1001 xmlNodePtr rptr = xmlNewChild(ptr, 0, BAD_CAST "diagnostics",
1003 yaz_srw_diagnostics(o, rptr, &res->diagnostics,
1004 &res->num_diagnostics, client_data, ns);
1014 int yaz_ucp_codec(ODR o, void * vptr, Z_SRW_PDU **handler_data,
1015 void *client_data, const char *ns)
1017 xmlNodePtr pptr = (xmlNodePtr) vptr;
1018 if (o->direction == ODR_DECODE)
1020 Z_SRW_PDU **p = handler_data;
1021 xmlNodePtr method = pptr->children;
1023 while (method && method->type == XML_TEXT_NODE)
1024 method = method->next;
1028 if (method->type != XML_ELEMENT_NODE)
1031 *p = yaz_srw_get_core_v_1_1(o);
1033 if (!xmlStrcmp(method->name, BAD_CAST "updateRequest"))
1035 xmlNodePtr ptr = method->children;
1036 Z_SRW_updateRequest *req;
1039 (*p)->which = Z_SRW_update_request;
1040 req = (*p)->u.update_request = (Z_SRW_updateRequest *)
1041 odr_malloc(o, sizeof(*req));
1045 req->recordVersion = 0;
1046 req->recordOldVersion = 0;
1047 req->record.recordData_buf = 0;
1048 req->record.recordData_len = 0;
1049 req->record.recordSchema = 0;
1050 req->record.recordPacking = 0;
1051 req->extra_record = 0;
1052 req->extraRequestData = 0;
1053 req->stylesheet = 0;
1055 for (; ptr; ptr = ptr->next)
1057 if (match_xsd_string(ptr, "version", o,
1058 &(*p)->srw_version))
1060 else if (match_xsd_string(ptr, "operation", o,
1062 /* backward compatible */
1064 if ( !strcmp(oper, "delete"))
1065 req->operation = "delete";
1066 else if (!strcmp(oper,"replace" ))
1067 req->operation = "replace";
1068 else if ( !strcmp( oper, "insert"))
1069 req->operation = "insert";
1072 else if (match_xsd_string(ptr, "action", o,
1075 if ( !strcmp(oper, "info:srw/action/1/delete"))
1076 req->operation = "delete";
1077 else if (!strcmp(oper,"info:srw/action/1/replace" ))
1078 req->operation = "replace";
1079 else if ( !strcmp( oper, "info:srw/action/1/create"))
1080 req->operation = "insert";
1083 else if (match_xsd_string(ptr, "recordId", o,
1085 ; /* backward compatible */
1086 else if (match_xsd_string(ptr, "recordIdentifier", o,
1089 else if (match_xsd_string(ptr, "recordVersion", o,
1090 &req->recordVersion))
1092 else if (match_element(ptr, "record"))
1093 yaz_srw_record(o, ptr, &req->record, &req->extra_record,
1095 else if (match_xsd_string(ptr, "stylesheet", o,
1098 else if (match_xsd_string(ptr, "database", o,
1103 else if (!xmlStrcmp(method->name, BAD_CAST "updateResponse"))
1105 xmlNodePtr ptr = method->children;
1106 Z_SRW_updateResponse *res;
1108 (*p)->which = Z_SRW_update_response;
1109 res = (*p)->u.update_response = (Z_SRW_updateResponse *)
1110 odr_malloc(o, sizeof(*res));
1112 res->operationStatus = 0;
1114 res->recordVersion = 0;
1115 res->recordChecksum = 0;
1116 res->diagnostics = 0;
1117 res->num_diagnostics = 0;
1118 res->record.recordData_buf = 0;
1119 res->record.recordData_len = 0;
1120 res->record.recordSchema = 0;
1121 res->record.recordPacking = 0;
1122 res->extra_record = 0;
1123 res->extraResponseData = 0;
1125 for (; ptr; ptr = ptr->next)
1127 if (match_xsd_string(ptr, "version", o,
1128 &(*p)->srw_version))
1130 else if (match_xsd_string(ptr, "operationStatus", o,
1131 &res->operationStatus ))
1133 else if (match_xsd_string(ptr, "recordId", o,
1135 ; /* backward compatible */
1136 else if (match_xsd_string(ptr, "recordIdentifier", o,
1139 else if (match_xsd_string(ptr, "recordVersion", o,
1140 &res->recordVersion ))
1142 else if (match_element(ptr, "record"))
1143 yaz_srw_record(o, ptr, &res->record, &res->extra_record,
1145 else if (match_element(ptr, "diagnostics"))
1146 yaz_srw_diagnostics(o, ptr, &res->diagnostics,
1147 &res->num_diagnostics,
1151 else if (!xmlStrcmp(method->name, BAD_CAST "explainUpdateRequest"))
1154 else if (!xmlStrcmp(method->name, BAD_CAST "explainUpdateResponse"))
1163 else if (o->direction == ODR_ENCODE)
1165 Z_SRW_PDU **p = handler_data;
1168 if ((*p)->which == Z_SRW_update_request)
1170 Z_SRW_updateRequest *req = (*p)->u.update_request;
1171 xmlNodePtr ptr = xmlNewChild(pptr, 0, BAD_CAST "updateRequest", 0);
1172 ns_srw = xmlNewNs(ptr, BAD_CAST ns, BAD_CAST "zu");
1173 xmlSetNs(ptr, ns_srw);
1175 add_xsd_string(ptr, "version", (*p)->srw_version);
1176 add_xsd_string(ptr, "stylesheet", req->stylesheet);
1177 add_xsd_string(ptr, "database", req->database);
1179 else if ((*p)->which == Z_SRW_update_response)
1181 Z_SRW_updateResponse *res = (*p)->u.update_response;
1182 xmlNodePtr ptr = xmlNewChild(pptr, 0, (xmlChar *)
1183 "updateResponse", 0);
1184 ns_srw = xmlNewNs(ptr, BAD_CAST ns, BAD_CAST "zu");
1185 xmlSetNs(ptr, ns_srw);
1187 add_xsd_string(ptr, "version", (*p)->srw_version);
1188 add_xsd_string(ptr, "operationStatus", res->operationStatus );
1189 add_xsd_string(ptr, "recordIdentifier", res->recordId );
1190 if (res->recordVersion)
1191 add_xsd_string(ptr, "recordVersion", res->recordVersion );
1192 if (res->recordChecksum)
1193 add_xsd_string(ptr, "recordChecksum", res->recordChecksum );
1194 if (res->record.recordData_len)
1196 xmlNodePtr rptr = xmlNewChild(ptr, 0, BAD_CAST "record", 0);
1197 yaz_srw_record(o, rptr, &res->record, &res->extra_record,
1200 if (res->num_diagnostics)
1202 xmlNodePtr rptr = xmlNewChild(ptr, 0, BAD_CAST "diagnostics", 0);
1203 yaz_srw_diagnostics(o, rptr, &res->diagnostics,
1204 &res->num_diagnostics, client_data, ns);
1206 if ( res->extraResponseData )
1207 add_xsd_string(ptr, "extraResponseData", res->extraResponseData);
1222 * indent-tabs-mode: nil
1224 * vim: shiftwidth=4 tabstop=8 expandtab