2 * Copyright (C) 1995-2005, Index Data ApS
5 * $Id: xmlquery.c,v 1.3 2006-02-02 15:00:58 adam Exp $
10 * \brief Query / XML conversions
17 #include <libxml/parser.h>
18 #include <libxml/tree.h>
20 #include <yaz/logrpn.h>
21 #include <yaz/xmlquery.h>
23 void yaz_query2xml_attribute_element(const Z_AttributeElement *element,
27 const char *setname = 0;
29 if (element->attributeSet)
32 attrset = oid_getentbyoid (element->attributeSet);
33 setname = attrset->desc;
36 if (element->which == Z_AttributeValue_numeric)
38 xmlNodePtr node = xmlNewChild(parent, 0, BAD_CAST "attr", 0);
41 xmlNewProp(node, BAD_CAST "set", BAD_CAST setname);
43 sprintf(formstr, "%d", *element->attributeType);
44 xmlNewProp(node, BAD_CAST "type", BAD_CAST formstr);
46 sprintf(formstr, "%d", *element->value.numeric);
47 xmlNewProp(node, BAD_CAST "value", BAD_CAST formstr);
49 else if (element->which == Z_AttributeValue_complex)
52 for (i = 0; i<element->value.complex->num_list; i++)
54 xmlNodePtr node = xmlNewChild(parent, 0, BAD_CAST "attr", 0);
57 xmlNewProp(node, BAD_CAST "set", BAD_CAST setname);
59 sprintf(formstr, "%d", *element->attributeType);
60 xmlNewProp(node, BAD_CAST "type", BAD_CAST formstr);
62 if (element->value.complex->list[i]->which ==
63 Z_StringOrNumeric_string)
65 xmlNewProp(node, BAD_CAST "value", BAD_CAST
66 element->value.complex->list[i]->u.string);
68 else if (element->value.complex->list[i]->which ==
69 Z_StringOrNumeric_numeric)
71 sprintf(formstr, "%d",
72 *element->value.complex->list[i]->u.numeric);
73 xmlNewProp(node, BAD_CAST "value", BAD_CAST formstr);
80 xmlNodePtr yaz_query2xml_term(const Z_Term *term,
84 xmlNodePtr node = xmlNewChild(parent, /* NS */ 0, BAD_CAST "term", 0);
92 t = xmlNewTextLen(BAD_CAST term->u.general->buf, term->u.general->len);
96 sprintf(formstr, "%d", *term->u.numeric);
97 t = xmlNewText(BAD_CAST formstr);
99 case Z_Term_characterString:
101 t = xmlNewText(BAD_CAST term->u.characterString);
106 case Z_Term_dateTime:
109 case Z_Term_external:
112 case Z_Term_integerAndUnit:
113 type ="integerAndUnit";
121 if (t) /* got a term node ? */
122 xmlAddChild(node, t);
124 xmlNewProp(node, BAD_CAST "type", BAD_CAST type);
128 xmlNodePtr yaz_query2xml_apt(const Z_AttributesPlusTerm *zapt,
131 xmlNodePtr node = xmlNewChild(parent, /* NS */ 0, BAD_CAST "apt", 0);
132 int num_attributes = zapt->attributes->num_attributes;
134 for (i = 0; i<num_attributes; i++)
135 yaz_query2xml_attribute_element(zapt->attributes->attributes[i], node);
136 yaz_query2xml_term(zapt->term, node);
142 void yaz_query2xml_operator(Z_Operator *op, xmlNodePtr node)
144 const char *type = 0;
153 case Z_Operator_and_not:
156 case Z_Operator_prox:
162 xmlNewProp(node, BAD_CAST "type", BAD_CAST type);
164 if (op->which == Z_Operator_prox)
168 if (op->u.prox->exclusion)
170 if (*op->u.prox->exclusion)
171 xmlNewProp(node, BAD_CAST "exclusion", BAD_CAST "true");
173 xmlNewProp(node, BAD_CAST "exclusion", BAD_CAST "false");
175 sprintf(formstr, "%d", *op->u.prox->distance);
176 xmlNewProp(node, BAD_CAST "distance", BAD_CAST formstr);
178 if (*op->u.prox->ordered)
179 xmlNewProp(node, BAD_CAST "ordered", BAD_CAST "true");
181 xmlNewProp(node, BAD_CAST "ordered", BAD_CAST "false");
183 sprintf(formstr, "%d", *op->u.prox->relationType);
184 xmlNewProp(node, BAD_CAST "relationType", BAD_CAST formstr);
186 switch(op->u.prox->which)
188 case Z_ProximityOperator_known:
189 sprintf(formstr, "%d", *op->u.prox->u.known);
190 xmlNewProp(node, BAD_CAST "knownProximityUnit",
194 xmlNewProp(node, BAD_CAST "privateProximityUnit",
201 xmlNodePtr yaz_query2xml_rpnstructure(const Z_RPNStructure *zs,
204 if (zs->which == Z_RPNStructure_complex)
206 Z_Complex *zc = zs->u.complex;
208 xmlNodePtr node = xmlNewChild(parent, /* NS */ 0, BAD_CAST "binary", 0);
210 yaz_query2xml_operator(zc->roperator, node);
211 yaz_query2xml_rpnstructure(zc->s1, node);
212 yaz_query2xml_rpnstructure(zc->s2, node);
215 else if (zs->which == Z_RPNStructure_simple)
217 if (zs->u.simple->which == Z_Operand_APT)
218 return yaz_query2xml_apt(zs->u.simple->u.attributesPlusTerm,
220 else if (zs->u.simple->which == Z_Operand_resultSetId)
221 return xmlNewChild(parent, /* NS */ 0, BAD_CAST "rset",
222 BAD_CAST zs->u.simple->u.resultSetId);
227 xmlNodePtr yaz_query2xml_rpn(const Z_RPNQuery *rpn, xmlNodePtr parent)
229 oident *attrset = oid_getentbyoid (rpn->attributeSetId);
230 if (attrset && attrset->value)
231 xmlNewProp(parent, BAD_CAST "set", BAD_CAST attrset->desc);
232 return yaz_query2xml_rpnstructure(rpn->RPNStructure, parent);
235 xmlNodePtr yaz_query2xml_ccl(const Odr_oct *ccl, xmlNodePtr node)
240 xmlNodePtr yaz_query2xml_z3958(const Odr_oct *ccl, xmlNodePtr node)
245 xmlNodePtr yaz_query2xml_cql(const char *cql, xmlNodePtr node)
250 void yaz_rpnquery2xml(const Z_RPNQuery *rpn, void *docp_void)
254 query.which = Z_Query_type_1;
255 query.u.type_1 = (Z_RPNQuery *) rpn;
256 yaz_query2xml(&query, docp_void);
259 void yaz_query2xml(const Z_Query *q, void *docp_void)
261 xmlDocPtr *docp = (xmlDocPtr *) docp_void;
262 xmlNodePtr top_node, child_node = 0;
263 const char *type = 0;
268 top_node = xmlNewNode(0, BAD_CAST "query");
273 case Z_Query_type_101:
275 child_node = yaz_query2xml_rpn(q->u.type_1, top_node);
279 child_node = yaz_query2xml_ccl(q->u.type_2, top_node);
281 case Z_Query_type_100:
283 child_node = yaz_query2xml_z3958(q->u.type_100, top_node);
285 case Z_Query_type_104:
286 if (q->u.type_104->which == Z_External_CQL)
289 child_node = yaz_query2xml_cql(q->u.type_104->u.cql, top_node);
293 if (child_node && type)
295 *docp = xmlNewDoc(BAD_CAST "1.0");
296 xmlDocSetRootElement(*docp, top_node); /* make it top node in doc */
298 /* set type attribute now */
299 xmlNewProp(top_node, BAD_CAST "type", BAD_CAST type);
304 xmlFreeNode(top_node);
308 void yaz_xml2query(const xmlNode node, Z_Query **q, ODR odr)
321 * indent-tabs-mode: nil
323 * vim: shiftwidth=4 tabstop=8 expandtab