2 * Copyright (C) 1995-2006, Index Data ApS
3 * See the file LICENSE for details.
5 * $Id: srw.c,v 1.52 2006-12-06 21:35:58 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,
23 xmlDocPtr doc = xmlParseMemory(val,len);
26 xmlNodePtr c = xmlNewChild(ptr, ns_ptr, BAD_CAST elem, 0);
27 xmlNodePtr t = xmlDocGetRootElement(doc);
28 xmlAddChild(c, xmlCopyNode(t,1));
34 xmlNodePtr add_xsd_string_n(xmlNodePtr ptr, const char *elem, const char *val,
39 xmlNodePtr c = xmlNewChild(ptr, 0, BAD_CAST elem, 0);
40 xmlNodePtr t = xmlNewTextLen(BAD_CAST val, len);
47 xmlNodePtr add_xsd_string_ns(xmlNodePtr ptr, const char *elem, const char *val,
52 xmlNodePtr c = xmlNewChild(ptr, ns_ptr, BAD_CAST elem, 0);
53 xmlNodePtr t = xmlNewText(BAD_CAST val);
60 xmlNodePtr add_xsd_string(xmlNodePtr ptr, const char *elem, const char *val)
62 return add_xsd_string_ns(ptr, elem, val, 0);
65 static void add_xsd_integer(xmlNodePtr ptr, const char *elem, const int *val)
70 sprintf(str, "%d", *val);
71 xmlNewTextChild(ptr, 0, BAD_CAST elem, BAD_CAST str);
75 static int match_element(xmlNodePtr ptr, const char *elem)
77 if (ptr->type == XML_ELEMENT_NODE && !xmlStrcmp(ptr->name, BAD_CAST elem))
86 static int match_xsd_string_n(xmlNodePtr ptr, const char *elem, ODR o,
90 struct _xmlAttr *attr;
92 if (!match_element(ptr, elem))
95 for (attr = ptr->properties; attr; attr = attr->next)
96 if (!strcmp(attr->name, "type") &&
97 attr->children && attr->children->type == XML_TEXT_NODE)
99 const char *t = strchr(attr->children->content, ':');
103 t = attr->children->content;
104 if (!strcmp(t, "string"))
111 if (!ptr || ptr->type != XML_TEXT_NODE)
116 *val = odr_strdup(o, (const char *) ptr->content);
118 *len = xmlStrlen(ptr->content);
123 static int match_xsd_string(xmlNodePtr ptr, const char *elem, ODR o,
126 return match_xsd_string_n(ptr, elem, o, val, 0);
130 /** \brief fixes NS for root node of record data (bug #740) */
131 static void fixup_xmlns(xmlNodePtr ptr, ODR o)
133 /* should go towards root and collect NS not defined in the record here! */
138 assert(p->type == XML_ELEMENT_NODE);
141 while (p && p->type != XML_ELEMENT_NODE)
146 for (; ns; ns = ns->next)
149 for (n = ptr->nsDef; n; n = n->next)
150 if ((n->prefix == 0 && ns->prefix == 0)
151 || (n->prefix && ns->prefix
152 && !strcmp((const char *) n->prefix,
153 (const char *) ns->prefix)))
159 xmlNsPtr new_ns = xmlCopyNamespace(ns);
161 new_ns->next = ptr->nsDef;
169 static int match_xsd_XML_n(xmlNodePtr ptr, const char *elem, ODR o,
170 char **val, int *len)
174 if (!match_element(ptr, elem))
178 while (ptr && (ptr->type == XML_TEXT_NODE || ptr->type == XML_COMMENT_NODE))
185 buf = xmlBufferCreate();
187 xmlNodeDump(buf, ptr->doc, ptr, 0, 0);
189 *val = odr_malloc(o, buf->use+1);
190 memcpy (*val, buf->content, buf->use);
191 (*val)[buf->use] = '\0';
201 static int match_xsd_integer(xmlNodePtr ptr, const char *elem, ODR o, int **val)
204 struct _xmlAttr *attr;
206 if (!match_element(ptr, elem))
209 for (attr = ptr->properties; attr; attr = attr->next)
210 if (!strcmp(attr->name, "type") &&
211 attr->children && attr->children->type == XML_TEXT_NODE)
213 const char *t = strchr(attr->children->content, ':');
217 t = attr->children->content;
218 if (!strcmp(t, "integer"))
225 if (!ptr || ptr->type != XML_TEXT_NODE)
227 *val = odr_intdup(o, atoi((const char *) ptr->content));
231 static int yaz_srw_record(ODR o, xmlNodePtr pptr, Z_SRW_record *rec,
232 Z_SRW_extra_record **extra,
233 void *client_data, const char *ns)
235 if (o->direction == ODR_DECODE)
237 Z_SRW_extra_record ex;
240 int pack = Z_SRW_recordPacking_string;
242 xmlNodePtr data_ptr = 0;
243 rec->recordSchema = 0;
244 rec->recordData_buf = 0;
245 rec->recordData_len = 0;
246 rec->recordPosition = 0;
249 ex.extraRecordData_buf = 0;
250 ex.extraRecordData_len = 0;
251 ex.recordIdentifier = 0;
253 for (ptr = pptr->children; ptr; ptr = ptr->next)
256 if (match_xsd_string(ptr, "recordSchema", o,
259 else if (match_xsd_string(ptr, "recordPacking", o, &spack))
261 if (spack && !strcmp(spack, "xml"))
262 pack = Z_SRW_recordPacking_XML;
263 if (spack && !strcmp(spack, "url"))
264 pack = Z_SRW_recordPacking_URL;
265 if (spack && !strcmp(spack, "string"))
266 pack = Z_SRW_recordPacking_string;
268 else if (match_xsd_integer(ptr, "recordPosition", o,
269 &rec->recordPosition))
271 else if (match_element(ptr, "recordData"))
273 /* save position of Data until after the loop
274 then we will know the packing (hopefully), and
275 unpacking is done once
279 else if (match_xsd_XML_n(ptr, "extraRecordData", o,
280 &ex.extraRecordData_buf,
281 &ex.extraRecordData_len) )
283 else if (match_xsd_string(ptr, "recordIdentifier", o,
284 &ex.recordIdentifier))
292 case Z_SRW_recordPacking_XML:
293 match_xsd_XML_n(data_ptr, "recordData", o,
294 &rec->recordData_buf, &rec->recordData_len);
296 case Z_SRW_recordPacking_URL:
297 /* just store it as a string.
298 leave it to the backend to collect the document */
299 match_xsd_string_n(data_ptr, "recordData", o,
300 &rec->recordData_buf, &rec->recordData_len);
302 case Z_SRW_recordPacking_string:
303 match_xsd_string_n(data_ptr, "recordData", o,
304 &rec->recordData_buf, &rec->recordData_len);
308 rec->recordPacking = pack;
309 if (ex.extraRecordData_buf || ex.recordIdentifier)
311 *extra = (Z_SRW_extra_record *)
312 odr_malloc(o, sizeof(Z_SRW_extra_record));
313 memcpy(*extra, &ex, sizeof(Z_SRW_extra_record));
316 else if (o->direction == ODR_ENCODE)
318 xmlNodePtr ptr = pptr;
319 int pack = rec->recordPacking;
320 add_xsd_string(ptr, "recordSchema", rec->recordSchema);
324 case Z_SRW_recordPacking_string:
325 add_xsd_string(ptr, "recordPacking", "string");
326 add_xsd_string_n(ptr, "recordData", rec->recordData_buf,
327 rec->recordData_len);
329 case Z_SRW_recordPacking_XML:
330 add_xsd_string(ptr, "recordPacking", "xml");
331 add_XML_n(ptr, "recordData", rec->recordData_buf,
332 rec->recordData_len, 0);
334 case Z_SRW_recordPacking_URL:
335 add_xsd_string(ptr, "recordPacking", "url");
336 add_xsd_string_n(ptr, "recordData", rec->recordData_buf,
337 rec->recordData_len);
340 if (rec->recordPosition)
341 add_xsd_integer(ptr, "recordPosition", rec->recordPosition );
344 if ((*extra)->recordIdentifier)
345 add_xsd_string(ptr, "recordIdentifier",
346 (*extra)->recordIdentifier);
347 if ((*extra)->extraRecordData_buf)
348 add_XML_n(ptr, "extraRecordData",
349 (*extra)->extraRecordData_buf,
350 (*extra)->extraRecordData_len, 0);
356 static int yaz_srw_records(ODR o, xmlNodePtr pptr, Z_SRW_record **recs,
357 Z_SRW_extra_record ***extra,
358 int *num, void *client_data, const char *ns)
360 if (o->direction == ODR_DECODE)
365 for (ptr = pptr->children; ptr; ptr = ptr->next)
367 if (ptr->type == XML_ELEMENT_NODE &&
368 !xmlStrcmp(ptr->name, BAD_CAST "record"))
373 *recs = (Z_SRW_record *) odr_malloc(o, *num * sizeof(**recs));
374 *extra = (Z_SRW_extra_record **) odr_malloc(o, *num * sizeof(**extra));
375 for (i = 0, ptr = pptr->children; ptr; ptr = ptr->next)
377 if (ptr->type == XML_ELEMENT_NODE &&
378 !xmlStrcmp(ptr->name, BAD_CAST "record"))
380 yaz_srw_record(o, ptr, *recs + i, *extra + i, client_data, ns);
385 else if (o->direction == ODR_ENCODE)
388 for (i = 0; i < *num; i++)
390 xmlNodePtr rptr = xmlNewChild(pptr, 0, BAD_CAST "record",
392 yaz_srw_record(o, rptr, (*recs)+i, (*extra ? *extra + i : 0),
399 static int yaz_srw_version(ODR o, xmlNodePtr pptr, Z_SRW_recordVersion *rec,
400 void *client_data, const char *ns)
402 if (o->direction == ODR_DECODE)
405 rec->versionType = 0;
406 rec->versionValue = 0;
407 for (ptr = pptr->children; ptr; ptr = ptr->next)
410 if (match_xsd_string(ptr, "versionType", o,
413 else if (match_xsd_string(ptr, "versionValue", o,
418 else if (o->direction == ODR_ENCODE)
420 xmlNodePtr ptr = pptr;
421 add_xsd_string(ptr, "versionType", rec->versionType);
422 add_xsd_string(ptr, "versionValue", rec->versionValue);
427 static int yaz_srw_versions(ODR o, xmlNodePtr pptr,
428 Z_SRW_recordVersion **vers,
429 int *num, void *client_data, const char *ns)
431 if (o->direction == ODR_DECODE)
436 for (ptr = pptr->children; ptr; ptr = ptr->next)
438 if (ptr->type == XML_ELEMENT_NODE &&
439 !xmlStrcmp(ptr->name, BAD_CAST "recordVersion"))
444 *vers = (Z_SRW_recordVersion *) odr_malloc(o, *num * sizeof(**vers));
445 for (i = 0, ptr = pptr->children; ptr; ptr = ptr->next)
447 if (ptr->type == XML_ELEMENT_NODE &&
448 !xmlStrcmp(ptr->name, BAD_CAST "recordVersion"))
450 yaz_srw_version(o, ptr, *vers + i, client_data, ns);
455 else if (o->direction == ODR_ENCODE)
458 for (i = 0; i < *num; i++)
460 xmlNodePtr rptr = xmlNewChild(pptr, 0, BAD_CAST "version",
462 yaz_srw_version(o, rptr, (*vers)+i, client_data, ns);
468 static int yaz_srw_diagnostics(ODR o, xmlNodePtr pptr, Z_SRW_diagnostic **recs,
469 int *num, void *client_data, const char *ns)
471 if (o->direction == ODR_DECODE)
476 for (ptr = pptr->children; ptr; ptr = ptr->next)
478 if (ptr->type == XML_ELEMENT_NODE &&
479 !xmlStrcmp(ptr->name, BAD_CAST "diagnostic"))
484 *recs = (Z_SRW_diagnostic *) odr_malloc(o, *num * sizeof(**recs));
485 for (i = 0; i < *num; i++)
488 (*recs)[i].details = 0;
489 (*recs)[i].message = 0;
491 for (i = 0, ptr = pptr->children; ptr; ptr = ptr->next)
493 if (ptr->type == XML_ELEMENT_NODE &&
494 !xmlStrcmp(ptr->name, BAD_CAST "diagnostic"))
498 (*recs)[i].details = 0;
499 (*recs)[i].message = 0;
500 for (rptr = ptr->children; rptr; rptr = rptr->next)
502 if (match_xsd_string(rptr, "uri", o,
505 else if (match_xsd_string(rptr, "details", o,
506 &(*recs)[i].details))
508 else if (match_xsd_string(rptr, "message", o,
509 &(*recs)[i].message))
516 else if (o->direction == ODR_ENCODE)
520 xmlNewNs(pptr, BAD_CAST YAZ_XMLNS_DIAG_v1_1, BAD_CAST "diag" );
521 for (i = 0; i < *num; i++)
523 const char *std_diag = "info:srw/diagnostic/1/";
524 const char *ucp_diag = "info:srw/diagnostic/12/";
525 xmlNodePtr rptr = xmlNewChild(pptr, ns_diag,
526 BAD_CAST "diagnostic", 0);
527 add_xsd_string(rptr, "uri", (*recs)[i].uri);
528 if ((*recs)[i].message)
529 add_xsd_string(rptr, "message", (*recs)[i].message);
530 else if ((*recs)[i].uri )
532 if (!strncmp((*recs)[i].uri, std_diag, strlen(std_diag)))
534 int no = atoi((*recs)[i].uri + strlen(std_diag));
535 const char *message = yaz_diag_srw_str(no);
537 add_xsd_string(rptr, "message", message);
539 else if (!strncmp((*recs)[i].uri, ucp_diag, strlen(ucp_diag)))
541 int no = atoi((*recs)[i].uri + strlen(ucp_diag));
542 const char *message = yaz_diag_sru_update_str(no);
544 add_xsd_string(rptr, "message", message);
547 add_xsd_string(rptr, "details", (*recs)[i].details);
553 static int yaz_srw_term(ODR o, xmlNodePtr pptr, Z_SRW_scanTerm *term,
554 void *client_data, const char *ns)
556 if (o->direction == ODR_DECODE)
560 term->numberOfRecords = 0;
561 term->displayTerm = 0;
562 term->whereInList = 0;
563 for (ptr = pptr->children; ptr; ptr = ptr->next)
565 if (match_xsd_string(ptr, "value", o, &term->value))
567 else if (match_xsd_integer(ptr, "numberOfRecords", o,
568 &term->numberOfRecords))
570 else if (match_xsd_string(ptr, "displayTerm", o,
573 else if (match_xsd_string(ptr, "whereInList", o,
578 else if (o->direction == ODR_ENCODE)
580 xmlNodePtr ptr = pptr;
581 add_xsd_string(ptr, "value", term->value);
582 add_xsd_integer(ptr, "numberOfRecords", term->numberOfRecords);
583 add_xsd_string(ptr, "displayTerm", term->displayTerm);
584 add_xsd_string(ptr, "whereInList", term->whereInList);
589 static int yaz_srw_terms(ODR o, xmlNodePtr pptr, Z_SRW_scanTerm **terms,
590 int *num, void *client_data, const char *ns)
592 if (o->direction == ODR_DECODE)
597 for (ptr = pptr->children; ptr; ptr = ptr->next)
599 if (ptr->type == XML_ELEMENT_NODE &&
600 !xmlStrcmp(ptr->name, BAD_CAST "term"))
605 *terms = (Z_SRW_scanTerm *) odr_malloc(o, *num * sizeof(**terms));
606 for (i = 0, ptr = pptr->children; ptr; ptr = ptr->next, i++)
608 if (ptr->type == XML_ELEMENT_NODE &&
609 !xmlStrcmp(ptr->name, BAD_CAST "term"))
610 yaz_srw_term(o, ptr, (*terms)+i, client_data, ns);
613 else if (o->direction == ODR_ENCODE)
616 for (i = 0; i < *num; i++)
618 xmlNodePtr rptr = xmlNewChild(pptr, 0, BAD_CAST "term", 0);
619 yaz_srw_term(o, rptr, (*terms)+i, client_data, ns);
625 int yaz_srw_codec(ODR o, void * vptr, Z_SRW_PDU **handler_data,
626 void *client_data, const char *ns)
628 xmlNodePtr pptr = (xmlNodePtr) vptr;
629 if (o->direction == ODR_DECODE)
631 Z_SRW_PDU **p = handler_data;
632 xmlNodePtr method = pptr->children;
634 while (method && method->type == XML_TEXT_NODE)
635 method = method->next;
639 if (method->type != XML_ELEMENT_NODE)
642 *p = yaz_srw_get_core_v_1_1(o);
644 if (!xmlStrcmp(method->name, BAD_CAST "searchRetrieveRequest"))
646 xmlNodePtr ptr = method->children;
647 Z_SRW_searchRetrieveRequest *req;
649 (*p)->which = Z_SRW_searchRetrieve_request;
650 req = (*p)->u.request = (Z_SRW_searchRetrieveRequest *)
651 odr_malloc(o, sizeof(*req));
652 req->query_type = Z_SRW_query_type_cql;
654 req->sort_type = Z_SRW_sort_type_none;
656 req->startRecord = 0;
657 req->maximumRecords = 0;
658 req->recordSchema = 0;
659 req->recordPacking = 0;
660 req->recordXPath = 0;
661 req->resultSetTTL = 0;
665 for (; ptr; ptr = ptr->next)
667 if (match_xsd_string(ptr, "version", o,
670 else if (match_xsd_string(ptr, "query", o,
672 req->query_type = Z_SRW_query_type_cql;
673 else if (match_xsd_string(ptr, "pQuery", o,
675 req->query_type = Z_SRW_query_type_pqf;
676 else if (match_xsd_string(ptr, "xQuery", o,
678 req->query_type = Z_SRW_query_type_xcql;
679 else if (match_xsd_integer(ptr, "startRecord", o,
682 else if (match_xsd_integer(ptr, "maximumRecords", o,
683 &req->maximumRecords))
685 else if (match_xsd_string(ptr, "recordPacking", o,
686 &req->recordPacking))
688 else if (match_xsd_string(ptr, "recordSchema", o,
691 else if (match_xsd_string(ptr, "recordXPath", o,
694 else if (match_xsd_integer(ptr, "resultSetTTL", o,
697 else if (match_xsd_string(ptr, "sortKeys", o,
698 &req->sort.sortKeys))
699 req->sort_type = Z_SRW_sort_type_sort;
700 else if (match_xsd_string(ptr, "stylesheet", o,
703 else if (match_xsd_string(ptr, "database", o,
707 if (!req->query.cql && !req->query.pqf && !req->query.xcql)
709 /* should put proper diagnostic here */
713 else if (!xmlStrcmp(method->name, BAD_CAST "searchRetrieveResponse"))
715 xmlNodePtr ptr = method->children;
716 Z_SRW_searchRetrieveResponse *res;
718 (*p)->which = Z_SRW_searchRetrieve_response;
719 res = (*p)->u.response = (Z_SRW_searchRetrieveResponse *)
720 odr_malloc(o, sizeof(*res));
722 res->numberOfRecords = 0;
723 res->resultSetId = 0;
724 res->resultSetIdleTime = 0;
726 res->num_records = 0;
727 res->diagnostics = 0;
728 res->num_diagnostics = 0;
729 res->nextRecordPosition = 0;
731 for (; ptr; ptr = ptr->next)
733 if (match_xsd_string(ptr, "version", o,
736 else if (match_xsd_integer(ptr, "numberOfRecords", o,
737 &res->numberOfRecords))
739 else if (match_xsd_string(ptr, "resultSetId", o,
742 else if (match_xsd_integer(ptr, "resultSetIdleTime", o,
743 &res->resultSetIdleTime))
745 else if (match_element(ptr, "records"))
746 yaz_srw_records(o, ptr, &res->records,
748 &res->num_records, client_data, ns);
749 else if (match_xsd_integer(ptr, "nextRecordPosition", o,
750 &res->nextRecordPosition))
752 else if (match_element(ptr, "diagnostics"))
753 yaz_srw_diagnostics(o, ptr, &res->diagnostics,
754 &res->num_diagnostics,
758 else if (!xmlStrcmp(method->name, BAD_CAST "explainRequest"))
760 Z_SRW_explainRequest *req;
761 xmlNodePtr ptr = method->children;
763 (*p)->which = Z_SRW_explain_request;
764 req = (*p)->u.explain_request = (Z_SRW_explainRequest *)
765 odr_malloc(o, sizeof(*req));
766 req->recordPacking = 0;
769 for (; ptr; ptr = ptr->next)
771 if (match_xsd_string(ptr, "version", o,
774 else if (match_xsd_string(ptr, "stylesheet", o,
777 else if (match_xsd_string(ptr, "recordPacking", o,
778 &req->recordPacking))
780 else if (match_xsd_string(ptr, "database", o,
785 else if (!xmlStrcmp(method->name, BAD_CAST "explainResponse"))
787 Z_SRW_explainResponse *res;
788 xmlNodePtr ptr = method->children;
790 (*p)->which = Z_SRW_explain_response;
791 res = (*p)->u.explain_response = (Z_SRW_explainResponse*)
792 odr_malloc(o, sizeof(*res));
793 res->diagnostics = 0;
794 res->num_diagnostics = 0;
795 res->record.recordSchema = 0;
796 res->record.recordData_buf = 0;
797 res->record.recordData_len = 0;
798 res->record.recordPosition = 0;
800 for (; ptr; ptr = ptr->next)
802 if (match_xsd_string(ptr, "version", o,
805 else if (match_element(ptr, "record"))
806 yaz_srw_record(o, ptr, &res->record, &res->extra_record,
808 else if (match_element(ptr, "diagnostics"))
809 yaz_srw_diagnostics(o, ptr, &res->diagnostics,
810 &res->num_diagnostics,
815 else if (!xmlStrcmp(method->name, BAD_CAST "scanRequest"))
817 Z_SRW_scanRequest *req;
818 xmlNodePtr ptr = method->children;
820 (*p)->which = Z_SRW_scan_request;
821 req = (*p)->u.scan_request = (Z_SRW_scanRequest *)
822 odr_malloc(o, sizeof(*req));
823 req->query_type = Z_SRW_query_type_cql;
824 req->scanClause.cql = 0;
825 req->responsePosition = 0;
826 req->maximumTerms = 0;
830 for (; ptr; ptr = ptr->next)
832 if (match_xsd_string(ptr, "version", o,
835 else if (match_xsd_string(ptr, "scanClause", o,
836 &req->scanClause.cql))
838 else if (match_xsd_string(ptr, "pScanClause", o,
839 &req->scanClause.pqf))
841 req->query_type = Z_SRW_query_type_pqf;
843 else if (match_xsd_integer(ptr, "responsePosition", o,
844 &req->responsePosition))
846 else if (match_xsd_integer(ptr, "maximumTerms", o,
849 else if (match_xsd_string(ptr, "stylesheet", o,
852 else if (match_xsd_string(ptr, "database", o,
857 else if (!xmlStrcmp(method->name, BAD_CAST "scanResponse"))
859 Z_SRW_scanResponse *res;
860 xmlNodePtr ptr = method->children;
862 (*p)->which = Z_SRW_scan_response;
863 res = (*p)->u.scan_response = (Z_SRW_scanResponse *)
864 odr_malloc(o, sizeof(*res));
867 res->diagnostics = 0;
868 res->num_diagnostics = 0;
870 for (; ptr; ptr = ptr->next)
872 if (match_xsd_string(ptr, "version", o,
875 else if (match_element(ptr, "terms"))
876 yaz_srw_terms(o, ptr, &res->terms,
877 &res->num_terms, client_data,
879 else if (match_element(ptr, "diagnostics"))
880 yaz_srw_diagnostics(o, ptr, &res->diagnostics,
881 &res->num_diagnostics,
891 else if (o->direction == ODR_ENCODE)
893 Z_SRW_PDU **p = handler_data;
896 if ((*p)->which == Z_SRW_searchRetrieve_request)
898 Z_SRW_searchRetrieveRequest *req = (*p)->u.request;
899 xmlNodePtr ptr = xmlNewChild(pptr, 0,
900 BAD_CAST "searchRetrieveRequest", 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 switch(req->query_type)
908 case Z_SRW_query_type_cql:
909 add_xsd_string(ptr, "query", req->query.cql);
911 case Z_SRW_query_type_xcql:
912 add_xsd_string(ptr, "xQuery", req->query.xcql);
914 case Z_SRW_query_type_pqf:
915 add_xsd_string(ptr, "pQuery", req->query.pqf);
918 add_xsd_integer(ptr, "startRecord", req->startRecord);
919 add_xsd_integer(ptr, "maximumRecords", req->maximumRecords);
920 add_xsd_string(ptr, "recordPacking", req->recordPacking);
921 add_xsd_string(ptr, "recordSchema", req->recordSchema);
922 add_xsd_string(ptr, "recordXPath", req->recordXPath);
923 add_xsd_integer(ptr, "resultSetTTL", req->resultSetTTL);
924 switch(req->sort_type)
926 case Z_SRW_sort_type_none:
928 case Z_SRW_sort_type_sort:
929 add_xsd_string(ptr, "sortKeys", req->sort.sortKeys);
931 case Z_SRW_sort_type_xSort:
932 add_xsd_string(ptr, "xSortKeys", req->sort.xSortKeys);
935 add_xsd_string(ptr, "stylesheet", req->stylesheet);
936 add_xsd_string(ptr, "database", req->database);
938 else if ((*p)->which == Z_SRW_searchRetrieve_response)
940 Z_SRW_searchRetrieveResponse *res = (*p)->u.response;
941 xmlNodePtr ptr = xmlNewChild(pptr, 0,
942 BAD_CAST "searchRetrieveResponse", 0);
943 ns_srw = xmlNewNs(ptr, BAD_CAST ns, BAD_CAST "zs");
944 xmlSetNs(ptr, ns_srw);
946 if ((*p)->srw_version)
947 add_xsd_string(ptr, "version", (*p)->srw_version);
948 add_xsd_integer(ptr, "numberOfRecords", res->numberOfRecords);
949 add_xsd_string(ptr, "resultSetId", res->resultSetId);
950 add_xsd_integer(ptr, "resultSetIdleTime", res->resultSetIdleTime);
951 if (res->num_records)
953 xmlNodePtr rptr = xmlNewChild(ptr, 0, BAD_CAST "records", 0);
954 yaz_srw_records(o, rptr, &res->records, &res->extra_records,
958 add_xsd_integer(ptr, "nextRecordPosition",
959 res->nextRecordPosition);
960 if (res->num_diagnostics)
962 xmlNodePtr rptr = xmlNewChild(ptr, 0, BAD_CAST "diagnostics",
964 yaz_srw_diagnostics(o, rptr, &res->diagnostics,
965 &res->num_diagnostics, client_data, ns);
968 else if ((*p)->which == Z_SRW_explain_request)
970 Z_SRW_explainRequest *req = (*p)->u.explain_request;
971 xmlNodePtr ptr = xmlNewChild(pptr, 0, BAD_CAST "explainRequest",
973 ns_srw = xmlNewNs(ptr, BAD_CAST ns, BAD_CAST "zs");
974 xmlSetNs(ptr, ns_srw);
976 add_xsd_string(ptr, "version", (*p)->srw_version);
977 add_xsd_string(ptr, "recordPacking", req->recordPacking);
978 add_xsd_string(ptr, "stylesheet", req->stylesheet);
979 add_xsd_string(ptr, "database", req->database);
981 else if ((*p)->which == Z_SRW_explain_response)
983 Z_SRW_explainResponse *res = (*p)->u.explain_response;
984 xmlNodePtr ptr = xmlNewChild(pptr, 0, BAD_CAST "explainResponse",
986 ns_srw = xmlNewNs(ptr, BAD_CAST ns, BAD_CAST "zs");
987 xmlSetNs(ptr, ns_srw);
989 add_xsd_string(ptr, "version", (*p)->srw_version);
992 xmlNodePtr ptr1 = xmlNewChild(ptr, 0, BAD_CAST "record", 0);
993 yaz_srw_record(o, ptr1, &res->record, &res->extra_record,
996 if (res->num_diagnostics)
998 xmlNodePtr rptr = xmlNewChild(ptr, 0, BAD_CAST "diagnostics",
1000 yaz_srw_diagnostics(o, rptr, &res->diagnostics,
1001 &res->num_diagnostics, client_data, ns);
1004 else if ((*p)->which == Z_SRW_scan_request)
1006 Z_SRW_scanRequest *req = (*p)->u.scan_request;
1007 xmlNodePtr ptr = xmlNewChild(pptr, 0, BAD_CAST "scanRequest", 0);
1008 ns_srw = xmlNewNs(ptr, BAD_CAST ns, BAD_CAST "zs");
1009 xmlSetNs(ptr, ns_srw);
1011 add_xsd_string(ptr, "version", (*p)->srw_version);
1012 switch(req->query_type)
1014 case Z_SRW_query_type_cql:
1015 add_xsd_string(ptr, "scanClause", req->scanClause.cql);
1017 case Z_SRW_query_type_pqf:
1018 add_xsd_string(ptr, "pScanClause", req->scanClause.pqf);
1021 add_xsd_integer(ptr, "responsePosition", req->responsePosition);
1022 add_xsd_integer(ptr, "maximumTerms", req->maximumTerms);
1023 add_xsd_string(ptr, "stylesheet", req->stylesheet);
1024 add_xsd_string(ptr, "database", req->database);
1026 else if ((*p)->which == Z_SRW_scan_response)
1028 Z_SRW_scanResponse *res = (*p)->u.scan_response;
1029 xmlNodePtr ptr = xmlNewChild(pptr, 0, BAD_CAST "scanResponse", 0);
1030 ns_srw = xmlNewNs(ptr, BAD_CAST ns, BAD_CAST "zs");
1031 xmlSetNs(ptr, ns_srw);
1033 add_xsd_string(ptr, "version", (*p)->srw_version);
1037 xmlNodePtr rptr = xmlNewChild(ptr, 0, BAD_CAST "terms", 0);
1038 yaz_srw_terms(o, rptr, &res->terms, &res->num_terms,
1041 if (res->num_diagnostics)
1043 xmlNodePtr rptr = xmlNewChild(ptr, 0, BAD_CAST "diagnostics",
1045 yaz_srw_diagnostics(o, rptr, &res->diagnostics,
1046 &res->num_diagnostics, client_data, ns);
1056 int yaz_ucp_codec(ODR o, void * vptr, Z_SRW_PDU **handler_data,
1057 void *client_data, const char *ns_ucp_str)
1059 xmlNodePtr pptr = (xmlNodePtr) vptr;
1060 const char *ns_srw_str = YAZ_XMLNS_SRU_v1_1;
1061 if (o->direction == ODR_DECODE)
1063 Z_SRW_PDU **p = handler_data;
1064 xmlNodePtr method = pptr->children;
1066 while (method && method->type == XML_TEXT_NODE)
1067 method = method->next;
1071 if (method->type != XML_ELEMENT_NODE)
1074 *p = yaz_srw_get_core_v_1_1(o);
1076 if (!xmlStrcmp(method->name, BAD_CAST "updateRequest"))
1078 xmlNodePtr ptr = method->children;
1079 Z_SRW_updateRequest *req;
1082 (*p)->which = Z_SRW_update_request;
1083 req = (*p)->u.update_request = (Z_SRW_updateRequest *)
1084 odr_malloc(o, sizeof(*req));
1088 req->recordVersions = 0;
1089 req->num_recordVersions = 0;
1091 req->extra_record = 0;
1092 req->extraRequestData_buf = 0;
1093 req->extraRequestData_len = 0;
1094 req->stylesheet = 0;
1096 for (; ptr; ptr = ptr->next)
1098 if (match_xsd_string(ptr, "version", o,
1099 &(*p)->srw_version))
1101 else if (match_xsd_string(ptr, "action", o,
1104 if ( !strcmp(oper, "info:srw/action/1/delete"))
1105 req->operation = "delete";
1106 else if (!strcmp(oper,"info:srw/action/1/replace" ))
1107 req->operation = "replace";
1108 else if ( !strcmp( oper, "info:srw/action/1/create"))
1109 req->operation = "insert";
1112 else if (match_xsd_string(ptr, "recordIdentifier", o,
1115 else if (match_element(ptr, "recordVersions" ) )
1116 yaz_srw_versions( o, ptr, &req->recordVersions,
1117 &req->num_recordVersions, client_data,
1119 else if (match_element(ptr, "record"))
1121 req->record = yaz_srw_get_record(o);
1122 yaz_srw_record(o, ptr, req->record, &req->extra_record,
1123 client_data, ns_ucp_str);
1125 else if (match_xsd_string(ptr, "stylesheet", o,
1128 else if (match_xsd_string(ptr, "database", o,
1133 else if (!xmlStrcmp(method->name, BAD_CAST "updateResponse"))
1135 xmlNodePtr ptr = method->children;
1136 Z_SRW_updateResponse *res;
1138 (*p)->which = Z_SRW_update_response;
1139 res = (*p)->u.update_response = (Z_SRW_updateResponse *)
1140 odr_malloc(o, sizeof(*res));
1142 res->operationStatus = 0;
1144 res->recordVersions = 0;
1145 res->num_recordVersions = 0;
1146 res->diagnostics = 0;
1147 res->num_diagnostics = 0;
1149 res->extra_record = 0;
1150 res->extraResponseData_buf = 0;
1151 res->extraResponseData_len = 0;
1153 for (; ptr; ptr = ptr->next)
1155 if (match_xsd_string(ptr, "version", o,
1156 &(*p)->srw_version))
1158 else if (match_xsd_string(ptr, "operationStatus", o,
1159 &res->operationStatus ))
1161 else if (match_xsd_string(ptr, "recordIdentifier", o,
1164 else if (match_element(ptr, "recordVersions" ))
1165 yaz_srw_versions(o, ptr, &res->recordVersions,
1166 &res->num_recordVersions,
1167 client_data, ns_ucp_str);
1168 else if (match_element(ptr, "record"))
1170 res->record = yaz_srw_get_record(o);
1171 yaz_srw_record(o, ptr, res->record, &res->extra_record,
1172 client_data, ns_ucp_str);
1174 else if (match_element(ptr, "diagnostics"))
1175 yaz_srw_diagnostics(o, ptr, &res->diagnostics,
1176 &res->num_diagnostics,
1177 client_data, ns_ucp_str);
1180 else if (!xmlStrcmp(method->name, BAD_CAST "explainUpdateRequest"))
1183 else if (!xmlStrcmp(method->name, BAD_CAST "explainUpdateResponse"))
1192 else if (o->direction == ODR_ENCODE)
1194 Z_SRW_PDU **p = handler_data;
1195 xmlNsPtr ns_ucp, ns_srw;
1198 if ((*p)->which == Z_SRW_update_request)
1200 Z_SRW_updateRequest *req = (*p)->u.update_request;
1201 xmlNodePtr ptr = xmlNewChild(pptr, 0, BAD_CAST "updateRequest", 0);
1202 ns_ucp = xmlNewNs(ptr, BAD_CAST ns_ucp_str, BAD_CAST "zu");
1203 xmlSetNs(ptr, ns_ucp);
1204 ns_srw = xmlNewNs(ptr, BAD_CAST ns_srw_str, BAD_CAST "zs");
1206 add_xsd_string_ns(ptr, "version", (*p)->srw_version, ns_srw);
1207 add_xsd_string(ptr, "action", req->operation);
1208 add_xsd_string(ptr, "recordIdentifier", req->recordId );
1209 if (req->recordVersions)
1210 yaz_srw_versions( o, ptr, &req->recordVersions,
1211 &req->num_recordVersions,
1212 client_data, ns_ucp_str);
1213 if (req->record && req->record->recordData_len)
1215 xmlNodePtr rptr = xmlNewChild(ptr, 0, BAD_CAST "record", 0);
1216 xmlSetNs(rptr, ns_srw);
1217 yaz_srw_record(o, rptr, req->record, &req->extra_record,
1218 client_data, ns_ucp_str);
1220 if (req->extraRequestData_len)
1222 add_XML_n(ptr, "extraRequestData",
1223 req->extraRequestData_buf,
1224 req->extraRequestData_len, ns_srw);
1226 add_xsd_string(ptr, "stylesheet", req->stylesheet);
1227 add_xsd_string(ptr, "database", req->database);
1229 else if ((*p)->which == Z_SRW_update_response)
1231 Z_SRW_updateResponse *res = (*p)->u.update_response;
1232 xmlNodePtr ptr = xmlNewChild(pptr, 0, (xmlChar *)
1233 "updateResponse", 0);
1234 ns_ucp = xmlNewNs(ptr, BAD_CAST ns_ucp_str, BAD_CAST "zu");
1235 xmlSetNs(ptr, ns_ucp);
1236 ns_srw = xmlNewNs(ptr, BAD_CAST ns_srw_str, BAD_CAST "zs");
1238 add_xsd_string_ns(ptr, "version", (*p)->srw_version, ns_srw);
1239 add_xsd_string(ptr, "operationStatus", res->operationStatus );
1240 add_xsd_string(ptr, "recordIdentifier", res->recordId );
1241 if (res->recordVersions)
1242 yaz_srw_versions(o, ptr, &res->recordVersions,
1243 &res->num_recordVersions,
1244 client_data, ns_ucp_str);
1245 if (res->record && res->record->recordData_len)
1247 xmlNodePtr rptr = xmlNewChild(ptr, 0, BAD_CAST "record", 0);
1248 xmlSetNs(rptr, ns_srw);
1249 yaz_srw_record(o, rptr, res->record, &res->extra_record,
1250 client_data, ns_ucp_str);
1252 if (res->num_diagnostics)
1255 xmlNewNs(pptr, BAD_CAST YAZ_XMLNS_DIAG_v1_1,
1258 xmlNodePtr rptr = xmlNewChild(ptr, ns_diag, BAD_CAST "diagnostics", 0);
1259 yaz_srw_diagnostics(o, rptr, &res->diagnostics,
1260 &res->num_diagnostics, client_data,
1263 if (res->extraResponseData_len)
1264 add_XML_n(ptr, "extraResponseData",
1265 res->extraResponseData_buf,
1266 res->extraResponseData_len, ns_srw);
1281 * indent-tabs-mode: nil
1283 * vim: shiftwidth=4 tabstop=8 expandtab