* Copyright (C) 1995-2007, Index Data ApS
* See the file LICENSE for details.
*
- * $Id: srw.c,v 1.55 2007-05-06 20:12:20 adam Exp $
+ * $Id: srw.c,v 1.58 2007-09-09 05:54:45 adam Exp $
*/
/**
* \file srw.c
char **val, int *len)
{
xmlBufferPtr buf;
- xmlNode *tmp;
if (!match_element(ptr, elem))
return 0;
- ptr = ptr->children;
- while (ptr && (ptr->type == XML_TEXT_NODE || ptr->type == XML_COMMENT_NODE))
- ptr = ptr->next;
- if (!ptr)
- return 0;
-
- /* copy node to get NS right (bug #740). */
- tmp = xmlCopyNode(ptr, 1);
-
buf = xmlBufferCreate();
-
- xmlNodeDump(buf, tmp->doc, tmp, 0, 0);
-
- xmlFreeNode(tmp);
+
+ /* Copy each element nodes at top.
+ In most cases there is only one root node.. At least one server
+ http://www.theeuropeanlibrary.org/sru/sru.pl
+ has multiple root nodes in recordData.
+ */
+ for (ptr = ptr->children; ptr; ptr = ptr->next)
+ {
+ if (ptr->type == XML_ELEMENT_NODE)
+ {
+ /* copy node to get NS right (bug #740). */
+ xmlNode *tmp = xmlCopyNode(ptr, 1);
+
+ xmlNodeDump(buf, tmp->doc, tmp, 0, 0);
+
+ xmlFreeNode(tmp);
+ }
+ }
*val = (char *) odr_malloc(o, buf->use+1);
memcpy (*val, buf->content, buf->use);
return 1;
}
+char *yaz_negotiate_sru_version(char *input_ver)
+{
+ if (!input_ver)
+ input_ver = "1.1";
+
+ if (!strcmp(input_ver, "1.1"))
+ return "1.1";
+ return "1.2"; /* our latest supported version */
+}
+
static int yaz_srw_record(ODR o, xmlNodePtr pptr, Z_SRW_record *rec,
Z_SRW_extra_record **extra,
void *client_data, const char *ns)
;
else if (match_xsd_string(ptr, "recordPacking", o, &spack))
{
- if (spack && !strcmp(spack, "xml"))
- pack = Z_SRW_recordPacking_XML;
- if (spack && !strcmp(spack, "url"))
- pack = Z_SRW_recordPacking_URL;
- if (spack && !strcmp(spack, "string"))
- pack = Z_SRW_recordPacking_string;
+ if (spack)
+ pack = yaz_srw_str_to_pack(spack);
}
else if (match_xsd_integer(ptr, "recordPosition", o,
&rec->recordPosition))
{
xmlNodePtr ptr = pptr;
int pack = rec->recordPacking;
- add_xsd_string(ptr, "recordSchema", rec->recordSchema);
+ const char *spack = yaz_srw_pack_to_str(pack);
+ add_xsd_string(ptr, "recordSchema", rec->recordSchema);
+ if (spack)
+ add_xsd_string(ptr, "recordPacking", spack);
switch(pack)
{
case Z_SRW_recordPacking_string:
- add_xsd_string(ptr, "recordPacking", "string");
add_xsd_string_n(ptr, "recordData", rec->recordData_buf,
rec->recordData_len);
break;
case Z_SRW_recordPacking_XML:
- add_xsd_string(ptr, "recordPacking", "xml");
add_XML_n(ptr, "recordData", rec->recordData_buf,
rec->recordData_len, 0);
break;
case Z_SRW_recordPacking_URL:
- add_xsd_string(ptr, "recordPacking", "url");
add_xsd_string_n(ptr, "recordData", rec->recordData_buf,
rec->recordData_len);
break;
return 0;
}
-static int yaz_srw_diagnostics(ODR o, xmlNodePtr pptr, Z_SRW_diagnostic **recs,
- int *num, void *client_data, const char *ns)
+
+static int yaz_srw_decode_diagnostics(ODR o, xmlNodePtr pptr,
+ Z_SRW_diagnostic **recs, int *num,
+ void *client_data, const char *ns)
+
{
- if (o->direction == ODR_DECODE)
+ int i;
+ xmlNodePtr ptr;
+ *num = 0;
+ for (ptr = pptr; ptr; ptr = ptr->next)
{
- int i;
- xmlNodePtr ptr;
- *num = 0;
- for (ptr = pptr->children; ptr; ptr = ptr->next)
- {
if (ptr->type == XML_ELEMENT_NODE &&
!xmlStrcmp(ptr->name, BAD_CAST "diagnostic"))
(*num)++;
- }
- if (!*num)
- return 1;
- *recs = (Z_SRW_diagnostic *) odr_malloc(o, *num * sizeof(**recs));
- for (i = 0; i < *num; i++)
+ }
+ if (!*num)
+ return 1;
+ *recs = (Z_SRW_diagnostic *) odr_malloc(o, *num * sizeof(**recs));
+ for (i = 0; i < *num; i++)
{
(*recs)[i].uri = 0;
(*recs)[i].details = 0;
(*recs)[i].message = 0;
}
- for (i = 0, ptr = pptr->children; ptr; ptr = ptr->next)
+ for (i = 0, ptr = pptr; ptr; ptr = ptr->next)
+ {
+ if (ptr->type == XML_ELEMENT_NODE &&
+ !xmlStrcmp(ptr->name, BAD_CAST "diagnostic"))
{
- if (ptr->type == XML_ELEMENT_NODE &&
- !xmlStrcmp(ptr->name, BAD_CAST "diagnostic"))
+ xmlNodePtr rptr;
+ (*recs)[i].uri = 0;
+ (*recs)[i].details = 0;
+ (*recs)[i].message = 0;
+ for (rptr = ptr->children; rptr; rptr = rptr->next)
{
- xmlNodePtr rptr;
- (*recs)[i].uri = 0;
- (*recs)[i].details = 0;
- (*recs)[i].message = 0;
- for (rptr = ptr->children; rptr; rptr = rptr->next)
- {
- if (match_xsd_string(rptr, "uri", o,
- &(*recs)[i].uri))
- ;
- else if (match_xsd_string(rptr, "details", o,
- &(*recs)[i].details))
- ;
- else if (match_xsd_string(rptr, "message", o,
- &(*recs)[i].message))
- ;
- }
- i++;
+ if (match_xsd_string(rptr, "uri", o,
+ &(*recs)[i].uri))
+ ;
+ else if (match_xsd_string(rptr, "details", o,
+ &(*recs)[i].details))
+ ;
+ else if (match_xsd_string(rptr, "message", o,
+ &(*recs)[i].message))
+ ;
}
+ i++;
}
}
+ return 0;
+}
+
+int sru_decode_surrogate_diagnostics(const char *buf, size_t len,
+ Z_SRW_diagnostic **diag,
+ int *num, ODR odr)
+{
+ int ret = 0;
+ xmlDocPtr doc = xmlParseMemory(buf, len);
+ if (doc)
+ {
+ xmlNodePtr ptr = xmlDocGetRootElement(doc);
+ while (ptr && ptr->type != XML_ELEMENT_NODE)
+ ptr = ptr->next;
+ if (ptr && ptr->ns
+ && !xmlStrcmp(ptr->ns->href,
+ BAD_CAST "http://www.loc.gov/zing/srw/diagnostic/"))
+ {
+ ret = yaz_srw_decode_diagnostics(odr, ptr, diag, num, 0, 0);
+ }
+ xmlFreeDoc(doc);
+ }
+ return ret;
+}
+
+static int yaz_srw_diagnostics(ODR o, xmlNodePtr pptr, Z_SRW_diagnostic **recs,
+ int *num, void *client_data, const char *ns)
+{
+ if (o->direction == ODR_DECODE)
+ {
+ return yaz_srw_decode_diagnostics(o, pptr->children, recs, num, client_data, ns);
+ }
else if (o->direction == ODR_ENCODE)
{
int i;
{
Z_SRW_PDU **p = handler_data;
xmlNodePtr method = pptr->children;
+ char *neg_version;
while (method && method->type == XML_TEXT_NODE)
method = method->next;
*p = 0;
return -1;
}
+ neg_version = yaz_negotiate_sru_version((*p)->srw_version);
+ if (neg_version)
+ (*p)->srw_version = neg_version;
}
else if (o->direction == ODR_ENCODE)
{