1 /* This file is part of the YAZ toolkit.
2 * Copyright (C) 1995-2008 Index Data
3 * See the file LICENSE for details.
7 * \brief Implements SRW/SRU package encoding and decoding
12 #include <libxml/parser.h>
13 #include <libxml/tree.h>
16 static void add_XML_n(xmlNodePtr ptr, const char *elem, char *val, int len,
21 xmlDocPtr doc = xmlParseMemory(val,len);
24 xmlNodePtr c = xmlNewChild(ptr, ns_ptr, BAD_CAST elem, 0);
25 xmlNodePtr t = xmlDocGetRootElement(doc);
26 xmlAddChild(c, xmlCopyNode(t,1));
32 xmlNodePtr add_xsd_string_n(xmlNodePtr ptr, const char *elem, const char *val,
37 xmlNodePtr c = xmlNewChild(ptr, 0, BAD_CAST elem, 0);
38 xmlNodePtr t = xmlNewTextLen(BAD_CAST val, len);
45 xmlNodePtr add_xsd_string_ns(xmlNodePtr ptr, const char *elem, const char *val,
50 xmlNodePtr c = xmlNewChild(ptr, ns_ptr, BAD_CAST elem, 0);
51 xmlNodePtr t = xmlNewText(BAD_CAST val);
58 xmlNodePtr add_xsd_string(xmlNodePtr ptr, const char *elem, const char *val)
60 return add_xsd_string_ns(ptr, elem, val, 0);
63 static void add_xsd_integer(xmlNodePtr ptr, const char *elem, const int *val)
68 sprintf(str, "%d", *val);
69 xmlNewTextChild(ptr, 0, BAD_CAST elem, BAD_CAST str);
73 static int match_element(xmlNodePtr ptr, const char *elem)
75 if (ptr->type == XML_ELEMENT_NODE && !xmlStrcmp(ptr->name, BAD_CAST elem))
84 static int match_xsd_string_n(xmlNodePtr ptr, const char *elem, ODR o,
88 struct _xmlAttr *attr;
90 if (!match_element(ptr, elem))
93 for (attr = ptr->properties; attr; attr = attr->next)
94 if (!strcmp(attr->name, "type") &&
95 attr->children && attr->children->type == XML_TEXT_NODE)
97 const char *t = strchr(attr->children->content, ':');
101 t = attr->children->content;
102 if (!strcmp(t, "string"))
109 if (!ptr || ptr->type != XML_TEXT_NODE)
114 *val = odr_strdup(o, (const char *) ptr->content);
116 *len = xmlStrlen(ptr->content);
121 static int match_xsd_string(xmlNodePtr ptr, const char *elem, ODR o,
124 return match_xsd_string_n(ptr, elem, o, val, 0);
127 static int match_xsd_XML_n(xmlNodePtr ptr, const char *elem, ODR o,
128 char **val, int *len)
132 if (!match_element(ptr, elem))
135 buf = xmlBufferCreate();
137 /* Copy each element nodes at top.
138 In most cases there is only one root node.. At least one server
139 http://www.theeuropeanlibrary.org/sru/sru.pl
140 has multiple root nodes in recordData.
142 for (ptr = ptr->children; ptr; ptr = ptr->next)
144 if (ptr->type == XML_ELEMENT_NODE)
146 /* copy node to get NS right (bug #740). */
147 xmlNode *tmp = xmlCopyNode(ptr, 1);
149 xmlNodeDump(buf, tmp->doc, tmp, 0, 0);
155 *val = (char *) odr_malloc(o, buf->use+1);
156 memcpy (*val, buf->content, buf->use);
157 (*val)[buf->use] = '\0';
167 static int match_xsd_integer(xmlNodePtr ptr, const char *elem, ODR o, int **val)
170 struct _xmlAttr *attr;
172 if (!match_element(ptr, elem))
175 for (attr = ptr->properties; attr; attr = attr->next)
176 if (!strcmp(attr->name, "type") &&
177 attr->children && attr->children->type == XML_TEXT_NODE)
179 const char *t = strchr(attr->children->content, ':');
183 t = attr->children->content;
184 if (!strcmp(t, "integer"))
191 if (!ptr || ptr->type != XML_TEXT_NODE)
193 *val = odr_intdup(o, atoi((const char *) ptr->content));
197 char *yaz_negotiate_sru_version(char *input_ver)
202 if (!strcmp(input_ver, "1.1"))
204 return "1.2"; /* our latest supported version */
207 static int yaz_srw_record(ODR o, xmlNodePtr pptr, Z_SRW_record *rec,
208 Z_SRW_extra_record **extra,
209 void *client_data, const char *ns)
211 if (o->direction == ODR_DECODE)
213 Z_SRW_extra_record ex;
216 int pack = Z_SRW_recordPacking_string;
218 xmlNodePtr data_ptr = 0;
219 rec->recordSchema = 0;
220 rec->recordData_buf = 0;
221 rec->recordData_len = 0;
222 rec->recordPosition = 0;
225 ex.extraRecordData_buf = 0;
226 ex.extraRecordData_len = 0;
227 ex.recordIdentifier = 0;
229 for (ptr = pptr->children; ptr; ptr = ptr->next)
232 if (match_xsd_string(ptr, "recordSchema", o,
235 else if (match_xsd_string(ptr, "recordPacking", o, &spack))
238 pack = yaz_srw_str_to_pack(spack);
240 else if (match_xsd_integer(ptr, "recordPosition", o,
241 &rec->recordPosition))
243 else if (match_element(ptr, "recordData"))
245 /* save position of Data until after the loop
246 then we will know the packing (hopefully), and
247 unpacking is done once
251 else if (match_xsd_XML_n(ptr, "extraRecordData", o,
252 &ex.extraRecordData_buf,
253 &ex.extraRecordData_len) )
255 else if (match_xsd_string(ptr, "recordIdentifier", o,
256 &ex.recordIdentifier))
264 case Z_SRW_recordPacking_XML:
265 match_xsd_XML_n(data_ptr, "recordData", o,
266 &rec->recordData_buf, &rec->recordData_len);
268 case Z_SRW_recordPacking_URL:
269 /* just store it as a string.
270 leave it to the backend to collect the document */
271 match_xsd_string_n(data_ptr, "recordData", o,
272 &rec->recordData_buf, &rec->recordData_len);
274 case Z_SRW_recordPacking_string:
275 match_xsd_string_n(data_ptr, "recordData", o,
276 &rec->recordData_buf, &rec->recordData_len);
280 rec->recordPacking = pack;
281 if (ex.extraRecordData_buf || ex.recordIdentifier)
283 *extra = (Z_SRW_extra_record *)
284 odr_malloc(o, sizeof(Z_SRW_extra_record));
285 memcpy(*extra, &ex, sizeof(Z_SRW_extra_record));
288 else if (o->direction == ODR_ENCODE)
290 xmlNodePtr ptr = pptr;
291 int pack = rec->recordPacking;
292 const char *spack = yaz_srw_pack_to_str(pack);
294 add_xsd_string(ptr, "recordSchema", rec->recordSchema);
296 add_xsd_string(ptr, "recordPacking", spack);
299 case Z_SRW_recordPacking_string:
300 add_xsd_string_n(ptr, "recordData", rec->recordData_buf,
301 rec->recordData_len);
303 case Z_SRW_recordPacking_XML:
304 add_XML_n(ptr, "recordData", rec->recordData_buf,
305 rec->recordData_len, 0);
307 case Z_SRW_recordPacking_URL:
308 add_xsd_string_n(ptr, "recordData", rec->recordData_buf,
309 rec->recordData_len);
312 if (rec->recordPosition)
313 add_xsd_integer(ptr, "recordPosition", rec->recordPosition );
316 if ((*extra)->recordIdentifier)
317 add_xsd_string(ptr, "recordIdentifier",
318 (*extra)->recordIdentifier);
319 if ((*extra)->extraRecordData_buf)
320 add_XML_n(ptr, "extraRecordData",
321 (*extra)->extraRecordData_buf,
322 (*extra)->extraRecordData_len, 0);
328 static int yaz_srw_records(ODR o, xmlNodePtr pptr, Z_SRW_record **recs,
329 Z_SRW_extra_record ***extra,
330 int *num, void *client_data, const char *ns)
332 if (o->direction == ODR_DECODE)
337 for (ptr = pptr->children; ptr; ptr = ptr->next)
339 if (ptr->type == XML_ELEMENT_NODE &&
340 !xmlStrcmp(ptr->name, BAD_CAST "record"))
345 *recs = (Z_SRW_record *) odr_malloc(o, *num * sizeof(**recs));
346 *extra = (Z_SRW_extra_record **) odr_malloc(o, *num * sizeof(**extra));
347 for (i = 0, ptr = pptr->children; ptr; ptr = ptr->next)
349 if (ptr->type == XML_ELEMENT_NODE &&
350 !xmlStrcmp(ptr->name, BAD_CAST "record"))
352 yaz_srw_record(o, ptr, *recs + i, *extra + i, client_data, ns);
357 else if (o->direction == ODR_ENCODE)
360 for (i = 0; i < *num; i++)
362 xmlNodePtr rptr = xmlNewChild(pptr, 0, BAD_CAST "record",
364 yaz_srw_record(o, rptr, (*recs)+i, (*extra ? *extra + i : 0),
371 static int yaz_srw_version(ODR o, xmlNodePtr pptr, Z_SRW_recordVersion *rec,
372 void *client_data, const char *ns)
374 if (o->direction == ODR_DECODE)
377 rec->versionType = 0;
378 rec->versionValue = 0;
379 for (ptr = pptr->children; ptr; ptr = ptr->next)
382 if (match_xsd_string(ptr, "versionType", o,
385 else if (match_xsd_string(ptr, "versionValue", o,
390 else if (o->direction == ODR_ENCODE)
392 xmlNodePtr ptr = pptr;
393 add_xsd_string(ptr, "versionType", rec->versionType);
394 add_xsd_string(ptr, "versionValue", rec->versionValue);
399 static int yaz_srw_versions(ODR o, xmlNodePtr pptr,
400 Z_SRW_recordVersion **vers,
401 int *num, void *client_data, const char *ns)
403 if (o->direction == ODR_DECODE)
408 for (ptr = pptr->children; ptr; ptr = ptr->next)
410 if (ptr->type == XML_ELEMENT_NODE &&
411 !xmlStrcmp(ptr->name, BAD_CAST "recordVersion"))
416 *vers = (Z_SRW_recordVersion *) odr_malloc(o, *num * sizeof(**vers));
417 for (i = 0, ptr = pptr->children; ptr; ptr = ptr->next)
419 if (ptr->type == XML_ELEMENT_NODE &&
420 !xmlStrcmp(ptr->name, BAD_CAST "recordVersion"))
422 yaz_srw_version(o, ptr, *vers + i, client_data, ns);
427 else if (o->direction == ODR_ENCODE)
430 for (i = 0; i < *num; i++)
432 xmlNodePtr rptr = xmlNewChild(pptr, 0, BAD_CAST "version",
434 yaz_srw_version(o, rptr, (*vers)+i, client_data, ns);
441 static int yaz_srw_decode_diagnostics(ODR o, xmlNodePtr pptr,
442 Z_SRW_diagnostic **recs, int *num,
443 void *client_data, const char *ns)
449 for (ptr = pptr; ptr; ptr = ptr->next)
451 if (ptr->type == XML_ELEMENT_NODE &&
452 !xmlStrcmp(ptr->name, BAD_CAST "diagnostic"))
457 *recs = (Z_SRW_diagnostic *) odr_malloc(o, *num * sizeof(**recs));
458 for (i = 0; i < *num; i++)
461 (*recs)[i].details = 0;
462 (*recs)[i].message = 0;
464 for (i = 0, ptr = pptr; ptr; ptr = ptr->next)
466 if (ptr->type == XML_ELEMENT_NODE &&
467 !xmlStrcmp(ptr->name, BAD_CAST "diagnostic"))
471 (*recs)[i].details = 0;
472 (*recs)[i].message = 0;
473 for (rptr = ptr->children; rptr; rptr = rptr->next)
475 if (match_xsd_string(rptr, "uri", o,
478 else if (match_xsd_string(rptr, "details", o,
479 &(*recs)[i].details))
481 else if (match_xsd_string(rptr, "message", o,
482 &(*recs)[i].message))
491 int sru_decode_surrogate_diagnostics(const char *buf, size_t len,
492 Z_SRW_diagnostic **diag,
496 xmlDocPtr doc = xmlParseMemory(buf, len);
499 xmlNodePtr ptr = xmlDocGetRootElement(doc);
500 while (ptr && ptr->type != XML_ELEMENT_NODE)
503 && !xmlStrcmp(ptr->ns->href,
504 BAD_CAST "http://www.loc.gov/zing/srw/diagnostic/"))
506 ret = yaz_srw_decode_diagnostics(odr, ptr, diag, num, 0, 0);
513 static int yaz_srw_diagnostics(ODR o, xmlNodePtr pptr, Z_SRW_diagnostic **recs,
514 int *num, void *client_data, const char *ns)
516 if (o->direction == ODR_DECODE)
518 return yaz_srw_decode_diagnostics(o, pptr->children, recs, num, client_data, ns);
520 else if (o->direction == ODR_ENCODE)
524 xmlNewNs(pptr, BAD_CAST YAZ_XMLNS_DIAG_v1_1, BAD_CAST "diag" );
525 for (i = 0; i < *num; i++)
527 const char *std_diag = "info:srw/diagnostic/1/";
528 const char *ucp_diag = "info:srw/diagnostic/12/";
529 xmlNodePtr rptr = xmlNewChild(pptr, ns_diag,
530 BAD_CAST "diagnostic", 0);
531 add_xsd_string(rptr, "uri", (*recs)[i].uri);
532 if ((*recs)[i].message)
533 add_xsd_string(rptr, "message", (*recs)[i].message);
534 else if ((*recs)[i].uri )
536 if (!strncmp((*recs)[i].uri, std_diag, strlen(std_diag)))
538 int no = atoi((*recs)[i].uri + strlen(std_diag));
539 const char *message = yaz_diag_srw_str(no);
541 add_xsd_string(rptr, "message", message);
543 else if (!strncmp((*recs)[i].uri, ucp_diag, strlen(ucp_diag)))
545 int no = atoi((*recs)[i].uri + strlen(ucp_diag));
546 const char *message = yaz_diag_sru_update_str(no);
548 add_xsd_string(rptr, "message", message);
551 add_xsd_string(rptr, "details", (*recs)[i].details);
557 static int yaz_srw_term(ODR o, xmlNodePtr pptr, Z_SRW_scanTerm *term,
558 void *client_data, const char *ns)
560 if (o->direction == ODR_DECODE)
564 term->numberOfRecords = 0;
565 term->displayTerm = 0;
566 term->whereInList = 0;
567 for (ptr = pptr->children; ptr; ptr = ptr->next)
569 if (match_xsd_string(ptr, "value", o, &term->value))
571 else if (match_xsd_integer(ptr, "numberOfRecords", o,
572 &term->numberOfRecords))
574 else if (match_xsd_string(ptr, "displayTerm", o,
577 else if (match_xsd_string(ptr, "whereInList", o,
582 else if (o->direction == ODR_ENCODE)
584 xmlNodePtr ptr = pptr;
585 add_xsd_string(ptr, "value", term->value);
586 add_xsd_integer(ptr, "numberOfRecords", term->numberOfRecords);
587 add_xsd_string(ptr, "displayTerm", term->displayTerm);
588 add_xsd_string(ptr, "whereInList", term->whereInList);
593 static int yaz_srw_terms(ODR o, xmlNodePtr pptr, Z_SRW_scanTerm **terms,
594 int *num, void *client_data, const char *ns)
596 if (o->direction == ODR_DECODE)
601 for (ptr = pptr->children; ptr; ptr = ptr->next)
603 if (ptr->type == XML_ELEMENT_NODE &&
604 !xmlStrcmp(ptr->name, BAD_CAST "term"))
609 *terms = (Z_SRW_scanTerm *) odr_malloc(o, *num * sizeof(**terms));
610 for (i = 0, ptr = pptr->children; ptr; ptr = ptr->next, i++)
612 if (ptr->type == XML_ELEMENT_NODE &&
613 !xmlStrcmp(ptr->name, BAD_CAST "term"))
614 yaz_srw_term(o, ptr, (*terms)+i, client_data, ns);
617 else if (o->direction == ODR_ENCODE)
620 for (i = 0; i < *num; i++)
622 xmlNodePtr rptr = xmlNewChild(pptr, 0, BAD_CAST "term", 0);
623 yaz_srw_term(o, rptr, (*terms)+i, client_data, ns);
629 int yaz_srw_codec(ODR o, void * vptr, Z_SRW_PDU **handler_data,
630 void *client_data, const char *ns)
632 xmlNodePtr pptr = (xmlNodePtr) vptr;
633 if (o->direction == ODR_DECODE)
635 Z_SRW_PDU **p = handler_data;
636 xmlNodePtr method = pptr->children;
639 while (method && method->type == XML_TEXT_NODE)
640 method = method->next;
644 if (method->type != XML_ELEMENT_NODE)
647 *p = yaz_srw_get_core_v_1_1(o);
649 if (!xmlStrcmp(method->name, BAD_CAST "searchRetrieveRequest"))
651 xmlNodePtr ptr = method->children;
652 Z_SRW_searchRetrieveRequest *req;
654 (*p)->which = Z_SRW_searchRetrieve_request;
655 req = (*p)->u.request = (Z_SRW_searchRetrieveRequest *)
656 odr_malloc(o, sizeof(*req));
657 req->query_type = Z_SRW_query_type_cql;
659 req->sort_type = Z_SRW_sort_type_none;
661 req->startRecord = 0;
662 req->maximumRecords = 0;
663 req->recordSchema = 0;
664 req->recordPacking = 0;
665 req->recordXPath = 0;
666 req->resultSetTTL = 0;
670 for (; ptr; ptr = ptr->next)
672 if (match_xsd_string(ptr, "version", o,
675 else if (match_xsd_string(ptr, "query", o,
677 req->query_type = Z_SRW_query_type_cql;
678 else if (match_xsd_string(ptr, "pQuery", o,
680 req->query_type = Z_SRW_query_type_pqf;
681 else if (match_xsd_string(ptr, "xQuery", o,
683 req->query_type = Z_SRW_query_type_xcql;
684 else if (match_xsd_integer(ptr, "startRecord", o,
687 else if (match_xsd_integer(ptr, "maximumRecords", o,
688 &req->maximumRecords))
690 else if (match_xsd_string(ptr, "recordPacking", o,
691 &req->recordPacking))
693 else if (match_xsd_string(ptr, "recordSchema", o,
696 else if (match_xsd_string(ptr, "recordXPath", o,
699 else if (match_xsd_integer(ptr, "resultSetTTL", o,
702 else if (match_xsd_string(ptr, "sortKeys", o,
703 &req->sort.sortKeys))
704 req->sort_type = Z_SRW_sort_type_sort;
705 else if (match_xsd_string(ptr, "stylesheet", o,
708 else if (match_xsd_string(ptr, "database", o,
712 if (!req->query.cql && !req->query.pqf && !req->query.xcql)
714 /* should put proper diagnostic here */
718 else if (!xmlStrcmp(method->name, BAD_CAST "searchRetrieveResponse"))
720 xmlNodePtr ptr = method->children;
721 Z_SRW_searchRetrieveResponse *res;
723 (*p)->which = Z_SRW_searchRetrieve_response;
724 res = (*p)->u.response = (Z_SRW_searchRetrieveResponse *)
725 odr_malloc(o, sizeof(*res));
727 res->numberOfRecords = 0;
728 res->resultSetId = 0;
729 res->resultSetIdleTime = 0;
731 res->num_records = 0;
732 res->diagnostics = 0;
733 res->num_diagnostics = 0;
734 res->nextRecordPosition = 0;
736 for (; ptr; ptr = ptr->next)
738 if (match_xsd_string(ptr, "version", o,
741 else if (match_xsd_integer(ptr, "numberOfRecords", o,
742 &res->numberOfRecords))
744 else if (match_xsd_string(ptr, "resultSetId", o,
747 else if (match_xsd_integer(ptr, "resultSetIdleTime", o,
748 &res->resultSetIdleTime))
750 else if (match_element(ptr, "records"))
751 yaz_srw_records(o, ptr, &res->records,
753 &res->num_records, client_data, ns);
754 else if (match_xsd_integer(ptr, "nextRecordPosition", o,
755 &res->nextRecordPosition))
757 else if (match_element(ptr, "diagnostics"))
758 yaz_srw_diagnostics(o, ptr, &res->diagnostics,
759 &res->num_diagnostics,
763 else if (!xmlStrcmp(method->name, BAD_CAST "explainRequest"))
765 Z_SRW_explainRequest *req;
766 xmlNodePtr ptr = method->children;
768 (*p)->which = Z_SRW_explain_request;
769 req = (*p)->u.explain_request = (Z_SRW_explainRequest *)
770 odr_malloc(o, sizeof(*req));
771 req->recordPacking = 0;
774 for (; ptr; ptr = ptr->next)
776 if (match_xsd_string(ptr, "version", o,
779 else if (match_xsd_string(ptr, "stylesheet", o,
782 else if (match_xsd_string(ptr, "recordPacking", o,
783 &req->recordPacking))
785 else if (match_xsd_string(ptr, "database", o,
790 else if (!xmlStrcmp(method->name, BAD_CAST "explainResponse"))
792 Z_SRW_explainResponse *res;
793 xmlNodePtr ptr = method->children;
795 (*p)->which = Z_SRW_explain_response;
796 res = (*p)->u.explain_response = (Z_SRW_explainResponse*)
797 odr_malloc(o, sizeof(*res));
798 res->diagnostics = 0;
799 res->num_diagnostics = 0;
800 res->record.recordSchema = 0;
801 res->record.recordData_buf = 0;
802 res->record.recordData_len = 0;
803 res->record.recordPosition = 0;
805 for (; ptr; ptr = ptr->next)
807 if (match_xsd_string(ptr, "version", o,
810 else if (match_element(ptr, "record"))
811 yaz_srw_record(o, ptr, &res->record, &res->extra_record,
813 else if (match_element(ptr, "diagnostics"))
814 yaz_srw_diagnostics(o, ptr, &res->diagnostics,
815 &res->num_diagnostics,
820 else if (!xmlStrcmp(method->name, BAD_CAST "scanRequest"))
822 Z_SRW_scanRequest *req;
823 xmlNodePtr ptr = method->children;
825 (*p)->which = Z_SRW_scan_request;
826 req = (*p)->u.scan_request = (Z_SRW_scanRequest *)
827 odr_malloc(o, sizeof(*req));
828 req->query_type = Z_SRW_query_type_cql;
829 req->scanClause.cql = 0;
830 req->responsePosition = 0;
831 req->maximumTerms = 0;
835 for (; ptr; ptr = ptr->next)
837 if (match_xsd_string(ptr, "version", o,
840 else if (match_xsd_string(ptr, "scanClause", o,
841 &req->scanClause.cql))
843 else if (match_xsd_string(ptr, "pScanClause", o,
844 &req->scanClause.pqf))
846 req->query_type = Z_SRW_query_type_pqf;
848 else if (match_xsd_integer(ptr, "responsePosition", o,
849 &req->responsePosition))
851 else if (match_xsd_integer(ptr, "maximumTerms", o,
854 else if (match_xsd_string(ptr, "stylesheet", o,
857 else if (match_xsd_string(ptr, "database", o,
862 else if (!xmlStrcmp(method->name, BAD_CAST "scanResponse"))
864 Z_SRW_scanResponse *res;
865 xmlNodePtr ptr = method->children;
867 (*p)->which = Z_SRW_scan_response;
868 res = (*p)->u.scan_response = (Z_SRW_scanResponse *)
869 odr_malloc(o, sizeof(*res));
872 res->diagnostics = 0;
873 res->num_diagnostics = 0;
875 for (; ptr; ptr = ptr->next)
877 if (match_xsd_string(ptr, "version", o,
880 else if (match_element(ptr, "terms"))
881 yaz_srw_terms(o, ptr, &res->terms,
882 &res->num_terms, client_data,
884 else if (match_element(ptr, "diagnostics"))
885 yaz_srw_diagnostics(o, ptr, &res->diagnostics,
886 &res->num_diagnostics,
895 neg_version = yaz_negotiate_sru_version((*p)->srw_version);
897 (*p)->srw_version = neg_version;
899 else if (o->direction == ODR_ENCODE)
901 Z_SRW_PDU **p = handler_data;
904 if ((*p)->which == Z_SRW_searchRetrieve_request)
906 Z_SRW_searchRetrieveRequest *req = (*p)->u.request;
907 xmlNodePtr ptr = xmlNewChild(pptr, 0,
908 BAD_CAST "searchRetrieveRequest", 0);
909 ns_srw = xmlNewNs(ptr, BAD_CAST ns, BAD_CAST "zs");
910 xmlSetNs(ptr, ns_srw);
912 if ((*p)->srw_version)
913 add_xsd_string(ptr, "version", (*p)->srw_version);
914 switch(req->query_type)
916 case Z_SRW_query_type_cql:
917 add_xsd_string(ptr, "query", req->query.cql);
919 case Z_SRW_query_type_xcql:
920 add_xsd_string(ptr, "xQuery", req->query.xcql);
922 case Z_SRW_query_type_pqf:
923 add_xsd_string(ptr, "pQuery", req->query.pqf);
926 add_xsd_integer(ptr, "startRecord", req->startRecord);
927 add_xsd_integer(ptr, "maximumRecords", req->maximumRecords);
928 add_xsd_string(ptr, "recordPacking", req->recordPacking);
929 add_xsd_string(ptr, "recordSchema", req->recordSchema);
930 add_xsd_string(ptr, "recordXPath", req->recordXPath);
931 add_xsd_integer(ptr, "resultSetTTL", req->resultSetTTL);
932 switch(req->sort_type)
934 case Z_SRW_sort_type_none:
936 case Z_SRW_sort_type_sort:
937 add_xsd_string(ptr, "sortKeys", req->sort.sortKeys);
939 case Z_SRW_sort_type_xSort:
940 add_xsd_string(ptr, "xSortKeys", req->sort.xSortKeys);
943 add_xsd_string(ptr, "stylesheet", req->stylesheet);
944 add_xsd_string(ptr, "database", req->database);
946 else if ((*p)->which == Z_SRW_searchRetrieve_response)
948 Z_SRW_searchRetrieveResponse *res = (*p)->u.response;
949 xmlNodePtr ptr = xmlNewChild(pptr, 0,
950 BAD_CAST "searchRetrieveResponse", 0);
951 ns_srw = xmlNewNs(ptr, BAD_CAST ns, BAD_CAST "zs");
952 xmlSetNs(ptr, ns_srw);
954 if ((*p)->srw_version)
955 add_xsd_string(ptr, "version", (*p)->srw_version);
956 add_xsd_integer(ptr, "numberOfRecords", res->numberOfRecords);
957 add_xsd_string(ptr, "resultSetId", res->resultSetId);
958 add_xsd_integer(ptr, "resultSetIdleTime", res->resultSetIdleTime);
959 if (res->num_records)
961 xmlNodePtr rptr = xmlNewChild(ptr, 0, BAD_CAST "records", 0);
962 yaz_srw_records(o, rptr, &res->records, &res->extra_records,
966 add_xsd_integer(ptr, "nextRecordPosition",
967 res->nextRecordPosition);
968 if (res->num_diagnostics)
970 xmlNodePtr rptr = xmlNewChild(ptr, 0, BAD_CAST "diagnostics",
972 yaz_srw_diagnostics(o, rptr, &res->diagnostics,
973 &res->num_diagnostics, client_data, ns);
976 else if ((*p)->which == Z_SRW_explain_request)
978 Z_SRW_explainRequest *req = (*p)->u.explain_request;
979 xmlNodePtr ptr = xmlNewChild(pptr, 0, BAD_CAST "explainRequest",
981 ns_srw = xmlNewNs(ptr, BAD_CAST ns, BAD_CAST "zs");
982 xmlSetNs(ptr, ns_srw);
984 add_xsd_string(ptr, "version", (*p)->srw_version);
985 add_xsd_string(ptr, "recordPacking", req->recordPacking);
986 add_xsd_string(ptr, "stylesheet", req->stylesheet);
987 add_xsd_string(ptr, "database", req->database);
989 else if ((*p)->which == Z_SRW_explain_response)
991 Z_SRW_explainResponse *res = (*p)->u.explain_response;
992 xmlNodePtr ptr = xmlNewChild(pptr, 0, BAD_CAST "explainResponse",
994 ns_srw = xmlNewNs(ptr, BAD_CAST ns, BAD_CAST "zs");
995 xmlSetNs(ptr, ns_srw);
997 add_xsd_string(ptr, "version", (*p)->srw_version);
1000 xmlNodePtr ptr1 = xmlNewChild(ptr, 0, BAD_CAST "record", 0);
1001 yaz_srw_record(o, ptr1, &res->record, &res->extra_record,
1004 if (res->num_diagnostics)
1006 xmlNodePtr rptr = xmlNewChild(ptr, 0, BAD_CAST "diagnostics",
1008 yaz_srw_diagnostics(o, rptr, &res->diagnostics,
1009 &res->num_diagnostics, client_data, ns);
1012 else if ((*p)->which == Z_SRW_scan_request)
1014 Z_SRW_scanRequest *req = (*p)->u.scan_request;
1015 xmlNodePtr ptr = xmlNewChild(pptr, 0, BAD_CAST "scanRequest", 0);
1016 ns_srw = xmlNewNs(ptr, BAD_CAST ns, BAD_CAST "zs");
1017 xmlSetNs(ptr, ns_srw);
1019 add_xsd_string(ptr, "version", (*p)->srw_version);
1020 switch(req->query_type)
1022 case Z_SRW_query_type_cql:
1023 add_xsd_string(ptr, "scanClause", req->scanClause.cql);
1025 case Z_SRW_query_type_pqf:
1026 add_xsd_string(ptr, "pScanClause", req->scanClause.pqf);
1029 add_xsd_integer(ptr, "responsePosition", req->responsePosition);
1030 add_xsd_integer(ptr, "maximumTerms", req->maximumTerms);
1031 add_xsd_string(ptr, "stylesheet", req->stylesheet);
1032 add_xsd_string(ptr, "database", req->database);
1034 else if ((*p)->which == Z_SRW_scan_response)
1036 Z_SRW_scanResponse *res = (*p)->u.scan_response;
1037 xmlNodePtr ptr = xmlNewChild(pptr, 0, BAD_CAST "scanResponse", 0);
1038 ns_srw = xmlNewNs(ptr, BAD_CAST ns, BAD_CAST "zs");
1039 xmlSetNs(ptr, ns_srw);
1041 add_xsd_string(ptr, "version", (*p)->srw_version);
1045 xmlNodePtr rptr = xmlNewChild(ptr, 0, BAD_CAST "terms", 0);
1046 yaz_srw_terms(o, rptr, &res->terms, &res->num_terms,
1049 if (res->num_diagnostics)
1051 xmlNodePtr rptr = xmlNewChild(ptr, 0, BAD_CAST "diagnostics",
1053 yaz_srw_diagnostics(o, rptr, &res->diagnostics,
1054 &res->num_diagnostics, client_data, ns);
1064 int yaz_ucp_codec(ODR o, void * vptr, Z_SRW_PDU **handler_data,
1065 void *client_data, const char *ns_ucp_str)
1067 xmlNodePtr pptr = (xmlNodePtr) vptr;
1068 const char *ns_srw_str = YAZ_XMLNS_SRU_v1_1;
1069 if (o->direction == ODR_DECODE)
1071 Z_SRW_PDU **p = handler_data;
1072 xmlNodePtr method = pptr->children;
1074 while (method && method->type == XML_TEXT_NODE)
1075 method = method->next;
1079 if (method->type != XML_ELEMENT_NODE)
1082 *p = yaz_srw_get_core_v_1_1(o);
1084 if (!xmlStrcmp(method->name, BAD_CAST "updateRequest"))
1086 xmlNodePtr ptr = method->children;
1087 Z_SRW_updateRequest *req;
1090 (*p)->which = Z_SRW_update_request;
1091 req = (*p)->u.update_request = (Z_SRW_updateRequest *)
1092 odr_malloc(o, sizeof(*req));
1096 req->recordVersions = 0;
1097 req->num_recordVersions = 0;
1099 req->extra_record = 0;
1100 req->extraRequestData_buf = 0;
1101 req->extraRequestData_len = 0;
1102 req->stylesheet = 0;
1104 for (; ptr; ptr = ptr->next)
1106 if (match_xsd_string(ptr, "version", o,
1107 &(*p)->srw_version))
1109 else if (match_xsd_string(ptr, "action", o,
1112 if ( !strcmp(oper, "info:srw/action/1/delete"))
1113 req->operation = "delete";
1114 else if (!strcmp(oper,"info:srw/action/1/replace" ))
1115 req->operation = "replace";
1116 else if ( !strcmp( oper, "info:srw/action/1/create"))
1117 req->operation = "insert";
1120 else if (match_xsd_string(ptr, "recordIdentifier", o,
1123 else if (match_element(ptr, "recordVersions" ) )
1124 yaz_srw_versions( o, ptr, &req->recordVersions,
1125 &req->num_recordVersions, client_data,
1127 else if (match_element(ptr, "record"))
1129 req->record = yaz_srw_get_record(o);
1130 yaz_srw_record(o, ptr, req->record, &req->extra_record,
1131 client_data, ns_ucp_str);
1133 else if (match_xsd_string(ptr, "stylesheet", o,
1136 else if (match_xsd_string(ptr, "database", o,
1141 else if (!xmlStrcmp(method->name, BAD_CAST "updateResponse"))
1143 xmlNodePtr ptr = method->children;
1144 Z_SRW_updateResponse *res;
1146 (*p)->which = Z_SRW_update_response;
1147 res = (*p)->u.update_response = (Z_SRW_updateResponse *)
1148 odr_malloc(o, sizeof(*res));
1150 res->operationStatus = 0;
1152 res->recordVersions = 0;
1153 res->num_recordVersions = 0;
1154 res->diagnostics = 0;
1155 res->num_diagnostics = 0;
1157 res->extra_record = 0;
1158 res->extraResponseData_buf = 0;
1159 res->extraResponseData_len = 0;
1161 for (; ptr; ptr = ptr->next)
1163 if (match_xsd_string(ptr, "version", o,
1164 &(*p)->srw_version))
1166 else if (match_xsd_string(ptr, "operationStatus", o,
1167 &res->operationStatus ))
1169 else if (match_xsd_string(ptr, "recordIdentifier", o,
1172 else if (match_element(ptr, "recordVersions" ))
1173 yaz_srw_versions(o, ptr, &res->recordVersions,
1174 &res->num_recordVersions,
1175 client_data, ns_ucp_str);
1176 else if (match_element(ptr, "record"))
1178 res->record = yaz_srw_get_record(o);
1179 yaz_srw_record(o, ptr, res->record, &res->extra_record,
1180 client_data, ns_ucp_str);
1182 else if (match_element(ptr, "diagnostics"))
1183 yaz_srw_diagnostics(o, ptr, &res->diagnostics,
1184 &res->num_diagnostics,
1185 client_data, ns_ucp_str);
1188 else if (!xmlStrcmp(method->name, BAD_CAST "explainUpdateRequest"))
1191 else if (!xmlStrcmp(method->name, BAD_CAST "explainUpdateResponse"))
1200 else if (o->direction == ODR_ENCODE)
1202 Z_SRW_PDU **p = handler_data;
1203 xmlNsPtr ns_ucp, ns_srw;
1206 if ((*p)->which == Z_SRW_update_request)
1208 Z_SRW_updateRequest *req = (*p)->u.update_request;
1209 xmlNodePtr ptr = xmlNewChild(pptr, 0, BAD_CAST "updateRequest", 0);
1210 ns_ucp = xmlNewNs(ptr, BAD_CAST ns_ucp_str, BAD_CAST "zu");
1211 xmlSetNs(ptr, ns_ucp);
1212 ns_srw = xmlNewNs(ptr, BAD_CAST ns_srw_str, BAD_CAST "zs");
1214 add_xsd_string_ns(ptr, "version", (*p)->srw_version, ns_srw);
1215 add_xsd_string(ptr, "action", req->operation);
1216 add_xsd_string(ptr, "recordIdentifier", req->recordId );
1217 if (req->recordVersions)
1218 yaz_srw_versions( o, ptr, &req->recordVersions,
1219 &req->num_recordVersions,
1220 client_data, ns_ucp_str);
1221 if (req->record && req->record->recordData_len)
1223 xmlNodePtr rptr = xmlNewChild(ptr, 0, BAD_CAST "record", 0);
1224 xmlSetNs(rptr, ns_srw);
1225 yaz_srw_record(o, rptr, req->record, &req->extra_record,
1226 client_data, ns_ucp_str);
1228 if (req->extraRequestData_len)
1230 add_XML_n(ptr, "extraRequestData",
1231 req->extraRequestData_buf,
1232 req->extraRequestData_len, ns_srw);
1234 add_xsd_string(ptr, "stylesheet", req->stylesheet);
1235 add_xsd_string(ptr, "database", req->database);
1237 else if ((*p)->which == Z_SRW_update_response)
1239 Z_SRW_updateResponse *res = (*p)->u.update_response;
1240 xmlNodePtr ptr = xmlNewChild(pptr, 0, (xmlChar *)
1241 "updateResponse", 0);
1242 ns_ucp = xmlNewNs(ptr, BAD_CAST ns_ucp_str, BAD_CAST "zu");
1243 xmlSetNs(ptr, ns_ucp);
1244 ns_srw = xmlNewNs(ptr, BAD_CAST ns_srw_str, BAD_CAST "zs");
1246 add_xsd_string_ns(ptr, "version", (*p)->srw_version, ns_srw);
1247 add_xsd_string(ptr, "operationStatus", res->operationStatus );
1248 add_xsd_string(ptr, "recordIdentifier", res->recordId );
1249 if (res->recordVersions)
1250 yaz_srw_versions(o, ptr, &res->recordVersions,
1251 &res->num_recordVersions,
1252 client_data, ns_ucp_str);
1253 if (res->record && res->record->recordData_len)
1255 xmlNodePtr rptr = xmlNewChild(ptr, 0, BAD_CAST "record", 0);
1256 xmlSetNs(rptr, ns_srw);
1257 yaz_srw_record(o, rptr, res->record, &res->extra_record,
1258 client_data, ns_ucp_str);
1260 if (res->num_diagnostics)
1263 xmlNewNs(pptr, BAD_CAST YAZ_XMLNS_DIAG_v1_1,
1266 xmlNodePtr rptr = xmlNewChild(ptr, ns_diag, BAD_CAST "diagnostics", 0);
1267 yaz_srw_diagnostics(o, rptr, &res->diagnostics,
1268 &res->num_diagnostics, client_data,
1271 if (res->extraResponseData_len)
1272 add_XML_n(ptr, "extraResponseData",
1273 res->extraResponseData_buf,
1274 res->extraResponseData_len, ns_srw);
1289 * indent-tabs-mode: nil
1291 * vim: shiftwidth=4 tabstop=8 expandtab