-/*
- * Copyright (C) 1995-2005, Index Data ApS
- * All rights reserved.
- *
- * $Id: xmlquery.c,v 1.4 2006-02-19 18:44:23 adam Exp $
+/* This file is part of the YAZ toolkit.
+ * Copyright (C) 1995-2009 Index Data
+ * See the file LICENSE for details.
*/
-/**
- * \file querytostr.c
- * \brief Query / XML conversions
- */
+/** \file xmlquery.c
+ \brief Query / XML conversions
+*/
#include <stdio.h>
#include <string.h>
#include <assert.h>
-#if HAVE_XML2
+#if YAZ_HAVE_XML2
#include <libxml/parser.h>
#include <libxml/tree.h>
#include <yaz/logrpn.h>
#include <yaz/xmlquery.h>
+#include <yaz/nmem_xml.h>
+#include <yaz/oid_db.h>
+
+static int check_diagnostic(const xmlNode *ptr, ODR odr,
+ int *error_code, const char **addinfo)
+{
+ if (ptr && ptr->type == XML_ELEMENT_NODE &&
+ !xmlStrcmp(ptr->name, BAD_CAST "diagnostic"))
+ {
+ struct _xmlAttr *attr;
+ const char *code_str = 0;
+ const char *addinfo_str = 0;
+ for (attr = ptr->properties; attr; attr = attr->next)
+ {
+ if (!xmlStrcmp(attr->name, BAD_CAST "code") &&
+ attr->children && attr->children->type == XML_TEXT_NODE)
+ code_str = (const char *) attr->children->content;
+ else if (!xmlStrcmp(attr->name, BAD_CAST "addinfo") &&
+ attr->children && attr->children->type == XML_TEXT_NODE)
+ addinfo_str = (const char *) attr->children->content;
+ else
+ {
+ *error_code = 1;
+ *addinfo = "bad attribute for diagnostic element";
+ return 1;
+ }
+ }
+ if (!code_str)
+ {
+ *error_code = 1;
+ *addinfo = "missing @code for diagnostic element";
+ return 1;
+ }
+ *error_code = atoi(code_str);
+ if (addinfo_str)
+ *addinfo = odr_strdup(odr, addinfo_str);
+ return 1;
+ }
+ else
+ return 0;
+}
void yaz_query2xml_attribute_element(const Z_AttributeElement *element,
xmlNodePtr parent)
{
char formstr[30];
const char *setname = 0;
+ char oid_name_str[OID_STR_MAX];
if (element->attributeSet)
{
- oident *attrset;
- attrset = oid_getentbyoid (element->attributeSet);
- setname = attrset->desc;
+ setname = yaz_oid_to_string_buf(element->attributeSet,
+ 0, oid_name_str);
}
if (element->which == Z_AttributeValue_numeric)
if (setname)
xmlNewProp(node, BAD_CAST "set", BAD_CAST setname);
- sprintf(formstr, "%d", *element->attributeType);
+ assert(*element->attributeType > 0 && *element->attributeType < 20);
+ sprintf(formstr, ODR_INT_PRINTF, *element->attributeType);
xmlNewProp(node, BAD_CAST "type", BAD_CAST formstr);
- sprintf(formstr, "%d", *element->value.numeric);
+ sprintf(formstr, ODR_INT_PRINTF, *element->value.numeric);
xmlNewProp(node, BAD_CAST "value", BAD_CAST formstr);
}
else if (element->which == Z_AttributeValue_complex)
if (setname)
xmlNewProp(node, BAD_CAST "set", BAD_CAST setname);
- sprintf(formstr, "%d", *element->attributeType);
+ sprintf(formstr, ODR_INT_PRINTF, *element->attributeType);
xmlNewProp(node, BAD_CAST "type", BAD_CAST formstr);
if (element->value.complex->list[i]->which ==
else if (element->value.complex->list[i]->which ==
Z_StringOrNumeric_numeric)
{
- sprintf(formstr, "%d",
+ sprintf(formstr, ODR_INT_PRINTF,
*element->value.complex->list[i]->u.numeric);
xmlNewProp(node, BAD_CAST "value", BAD_CAST formstr);
}
break;
case Z_Term_numeric:
type = "numeric";
- sprintf(formstr, "%d", *term->u.numeric);
+ sprintf(formstr, ODR_INT_PRINTF, *term->u.numeric);
t = xmlNewText(BAD_CAST formstr);
break;
case Z_Term_characterString:
else
xmlNewProp(node, BAD_CAST "exclusion", BAD_CAST "false");
}
- sprintf(formstr, "%d", *op->u.prox->distance);
+ sprintf(formstr, ODR_INT_PRINTF, *op->u.prox->distance);
xmlNewProp(node, BAD_CAST "distance", BAD_CAST formstr);
if (*op->u.prox->ordered)
else
xmlNewProp(node, BAD_CAST "ordered", BAD_CAST "false");
- sprintf(formstr, "%d", *op->u.prox->relationType);
+ sprintf(formstr, ODR_INT_PRINTF, *op->u.prox->relationType);
xmlNewProp(node, BAD_CAST "relationType", BAD_CAST formstr);
switch(op->u.prox->which)
{
case Z_ProximityOperator_known:
- sprintf(formstr, "%d", *op->u.prox->u.known);
+ sprintf(formstr, ODR_INT_PRINTF, *op->u.prox->u.known);
xmlNewProp(node, BAD_CAST "knownProximityUnit",
BAD_CAST formstr);
break;
{
Z_Complex *zc = zs->u.complex;
- xmlNodePtr node = xmlNewChild(parent, /* NS */ 0, BAD_CAST "binary", 0);
+ xmlNodePtr node = xmlNewChild(parent, /* NS */ 0, BAD_CAST "operator", 0);
if (zc->roperator)
yaz_query2xml_operator(zc->roperator, node);
yaz_query2xml_rpnstructure(zc->s1, node);
xmlNodePtr yaz_query2xml_rpn(const Z_RPNQuery *rpn, xmlNodePtr parent)
{
- oident *attrset = oid_getentbyoid (rpn->attributeSetId);
- if (attrset && attrset->value)
- xmlNewProp(parent, BAD_CAST "set", BAD_CAST attrset->desc);
+ if (rpn->attributeSetId)
+ {
+ char oid_name_str[OID_STR_MAX];
+ const char *setname = yaz_oid_to_string_buf(rpn->attributeSetId,
+ 0, oid_name_str);
+ if (setname)
+ xmlNewProp(parent, BAD_CAST "set", BAD_CAST setname);
+ }
return yaz_query2xml_rpnstructure(rpn->RPNStructure, parent);
}
return 0;
}
-void yaz_rpnquery2xml(const Z_RPNQuery *rpn, void *docp_void)
+void yaz_rpnquery2xml(const Z_RPNQuery *rpn, xmlDocPtr *docp)
{
Z_Query query;
query.which = Z_Query_type_1;
query.u.type_1 = (Z_RPNQuery *) rpn;
- yaz_query2xml(&query, docp_void);
+ yaz_query2xml(&query, docp);
}
-void yaz_query2xml(const Z_Query *q, void *docp_void)
+void yaz_query2xml(const Z_Query *q, xmlDocPtr *docp)
{
- xmlDocPtr *docp = (xmlDocPtr *) docp_void;
- xmlNodePtr top_node, child_node = 0;
- const char *type = 0;
+ xmlNodePtr top_node, q_node = 0, child_node = 0;
assert(q);
assert(docp);
{
case Z_Query_type_1:
case Z_Query_type_101:
- type = "rpn";
- child_node = yaz_query2xml_rpn(q->u.type_1, top_node);
+ q_node = xmlNewChild(top_node, 0, BAD_CAST "rpn", 0);
+ child_node = yaz_query2xml_rpn(q->u.type_1, q_node);
break;
case Z_Query_type_2:
- type = "ccl";
- child_node = yaz_query2xml_ccl(q->u.type_2, top_node);
+ q_node = xmlNewChild(top_node, 0, BAD_CAST "ccl", 0);
+ child_node = yaz_query2xml_ccl(q->u.type_2, q_node);
break;
case Z_Query_type_100:
- type = "z39.58";
- child_node = yaz_query2xml_z3958(q->u.type_100, top_node);
+ q_node = xmlNewChild(top_node, 0, BAD_CAST "z39.58", 0);
+ child_node = yaz_query2xml_z3958(q->u.type_100, q_node);
break;
case Z_Query_type_104:
if (q->u.type_104->which == Z_External_CQL)
{
- type = "cql";
- child_node = yaz_query2xml_cql(q->u.type_104->u.cql, top_node);
+ q_node = xmlNewChild(top_node, 0, BAD_CAST "cql", 0);
+ child_node = yaz_query2xml_cql(q->u.type_104->u.cql, q_node);
}
}
- if (child_node && type)
+ if (child_node && q_node)
{
*docp = xmlNewDoc(BAD_CAST "1.0");
xmlDocSetRootElement(*docp, top_node); /* make it top node in doc */
-
- /* set type attribute now */
- xmlNewProp(top_node, BAD_CAST "type", BAD_CAST type);
}
else
{
bool_t *boolVal(ODR odr, const char *str)
{
if (*str == '\0' || strchr("0fF", *str))
- return odr_intdup(odr, 0);
- return odr_intdup(odr, 1);
+ return odr_booldup(odr, 0);
+ return odr_booldup(odr, 1);
}
-int *intVal(ODR odr, const char *str)
+Odr_int *intVal(ODR odr, const char *str)
{
return odr_intdup(odr, atoi(str));
}
if (atval)
pop->ordered = boolVal(odr, atval);
else
- pop->ordered = odr_intdup(odr, 1);
+ pop->ordered = odr_booldup(odr, 1);
atval = (const char *) xmlGetProp((xmlNodePtr) ptr,
BAD_CAST "relationType");
*elem = (Z_AttributeElement *) odr_malloc(odr, sizeof(**elem));
if (set)
- (*elem)->attributeSet = yaz_str_to_z3950oid(odr, CLASS_ATTSET,
- (const char *)set);
+ (*elem)->attributeSet = yaz_string_to_oid_odr(yaz_oid_std(),
+ CLASS_ATTSET,
+ (const char *) set,
+ odr);
else
(*elem)->attributeSet = 0;
(*elem)->attributeType = intVal(odr, (const char *) type);
char *strVal(const xmlNode *ptr_cdata, ODR odr)
{
- char *cdata;
- int len = 0;
- const xmlNode *ptr;
-
- for (ptr = ptr_cdata; ptr; ptr = ptr->next)
- if (ptr->type == XML_TEXT_NODE)
- len += xmlStrlen(ptr->content);
- cdata = (char *) odr_malloc(odr, len+1);
- *cdata = '\0';
- for (ptr = ptr_cdata; ptr; ptr = ptr->next)
- if (ptr->type == XML_TEXT_NODE)
- strcat(cdata, (const char *) ptr->content);
- return cdata;
+ return nmem_text_node_cdata(ptr_cdata, odr_getmem(odr));
}
void yaz_xml2query_term(const xmlNode *ptr,
else
break;
}
+ if (check_diagnostic(ptr, odr, error_code, addinfo))
+ return;
+
if (ptr && ptr->type == XML_ELEMENT_NODE)
{
if (!xmlStrcmp(ptr->name, BAD_CAST "term"))
if (!ptr || ptr->type != XML_ELEMENT_NODE)
{
*error_code = 1;
- *addinfo = "missing rpn structure node";
+ *addinfo = "missing rpn operator, rset, apt node";
return;
}
+ if (check_diagnostic(ptr, odr, error_code, addinfo))
+ return;
+
*zs = (Z_RPNStructure *) odr_malloc(odr, sizeof(Z_RPNStructure));
- if (!xmlStrcmp(ptr->name, BAD_CAST "binary"))
+ if (!xmlStrcmp(ptr->name, BAD_CAST "operator"))
{
- Z_Complex *zc = odr_malloc(odr, sizeof(Z_Complex));
+ Z_Complex *zc = (Z_Complex *) odr_malloc(odr, sizeof(Z_Complex));
(*zs)->which = Z_RPNStructure_complex;
(*zs)->u.complex = zc;
*query = (Z_RPNQuery*) odr_malloc(odr, sizeof(Z_RPNQuery));
if (set)
- (*query)->attributeSetId = yaz_str_to_z3950oid(odr, CLASS_ATTSET, set);
+ (*query)->attributeSetId = yaz_string_to_oid_odr(yaz_oid_std(),
+ CLASS_ATTSET, set, odr);
else
(*query)->attributeSetId = 0;
yaz_xml2query_rpnstructure(ptr->children, &(*query)->RPNStructure,
static void yaz_xml2query_(const xmlNode *ptr, Z_Query **query, ODR odr,
int *error_code, const char **addinfo)
{
+ if (check_diagnostic(ptr, odr, error_code, addinfo))
+ return;
if (ptr && ptr->type == XML_ELEMENT_NODE &&
!xmlStrcmp(ptr->name, BAD_CAST "query"))
{
- const char *type = (const char *)
- xmlGetProp((xmlNodePtr) ptr, BAD_CAST "type");
+ const char *type;
+ ptr = ptr->children;
+ while (ptr && ptr->type != XML_ELEMENT_NODE)
+ ptr = ptr->next;
+ if (!ptr || ptr->type != XML_ELEMENT_NODE)
+ {
+ *error_code = 1;
+ *addinfo = "missing query content";
+ return;
+ }
+ type = (const char *) ptr->name;
+
*query = (Z_Query*) odr_malloc(odr, sizeof(Z_Query));
if (!type || !strcmp(type, "rpn"))
{
}
}
-void yaz_xml2query(const void *xmlnodep, Z_Query **query, ODR odr,
+void yaz_xml2query(const xmlNode *xmlnodep, Z_Query **query, ODR odr,
int *error_code, const char **addinfo)
{
- return yaz_xml2query_(xmlnodep, query, odr, error_code, addinfo);
+ yaz_xml2query_(xmlnodep, query, odr, error_code, addinfo);
}
-/* HAVE_XML2 */
+/* YAZ_HAVE_XML2 */
#endif
/*
* Local variables:
* c-basic-offset: 4
+ * c-file-style: "Stroustrup"
* indent-tabs-mode: nil
* End:
* vim: shiftwidth=4 tabstop=8 expandtab
*/
+