2 * Copyright (C) 1995-2005, Index Data ApS
5 * $Id: xmlquery.c,v 1.1 2006-01-27 17:28:16 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 xmlNodePtr yaz_query2xml_attribute_element(const Z_AttributeElement *element,
26 xmlNodePtr node = xmlNewChild(parent, 0, BAD_CAST "attr", 0);
30 if (element->attributeSet)
33 attrset = oid_getentbyoid (element->attributeSet);
34 setname = attrset->desc;
36 switch (element->which)
38 case Z_AttributeValue_numeric:
39 wrbuf_printf(b,"@attr %s%s%d=%d ", setname, sep,
40 *element->attributeType, *element->value.numeric);
42 case Z_AttributeValue_complex:
43 wrbuf_printf(b,"@attr %s%s\"%d=", setname, sep,
44 *element->attributeType);
45 for (i = 0; i<element->value.complex->num_list; i++)
49 if (element->value.complex->list[i]->which ==
50 Z_StringOrNumeric_string)
51 wrbuf_printf (b, "%s",
52 element->value.complex->list[i]->u.string);
53 else if (element->value.complex->list[i]->which ==
54 Z_StringOrNumeric_numeric)
55 wrbuf_printf (b, "%d",
56 *element->value.complex->list[i]->u.numeric);
58 wrbuf_printf(b, "\" ");
61 wrbuf_printf (b, "@attr 1=unknown ");
68 xmlNodePtr yaz_query2xml_term(const Z_Term *term,
72 xmlNodePtr node = xmlNewChild(parent, /* NS */ 0, BAD_CAST "term", 0);
78 t = xmlNewTextLen(BAD_CAST term->u.general->buf, term->u.general->len);
80 case Z_Term_characterString:
81 t = xmlNewText(BAD_CAST term->u.characterString);
84 sprintf(formstr, "%d", *term->u.numeric);
85 t = xmlNewText(BAD_CAST formstr);
92 if (t) /* got a term node ? */
97 xmlNodePtr yaz_query2xml_apt(const Z_AttributesPlusTerm *zapt,
100 xmlNodePtr node = xmlNewChild(parent, /* NS */ 0, BAD_CAST "apt", 0);
101 int num_attributes = zapt->attributes->num_attributes;
103 for (i = 0; i<num_attributes; i++)
104 yaz_query2xml_attribute_element(zapt->attributes->attributes[i], node);
105 yaz_query2xml_term(zapt->term, node);
110 xmlNodePtr yaz_query2xml_rpnstructure(const Z_RPNStructure *zs,
113 if (zs->which == Z_RPNStructure_complex)
117 Z_Operator *op = zs->u.complex->roperator;
118 wrbuf_printf(b, "@%s ", complex_op_name(op) );
119 if (op->which== Z_Operator_prox)
121 if (!op->u.prox->exclusion)
123 else if (*op->u.prox->exclusion)
128 wrbuf_printf(b, " %d %d %d ", *op->u.prox->distance,
129 *op->u.prox->ordered,
130 *op->u.prox->relationType);
132 switch(op->u.prox->which)
134 case Z_ProximityOperator_known:
137 case Z_ProximityOperator_private:
141 wrbuf_printf(b, "%d", op->u.prox->which);
143 if (op->u.prox->u.known)
144 wrbuf_printf(b, " %d ", *op->u.prox->u.known);
146 wrbuf_printf(b, " 0 ");
148 yaz_rpnstructure_to_wrbuf(b,zs->u.complex->s1);
149 yaz_rpnstructure_to_wrbuf(b,zs->u.complex->s2);
152 else if (zs->which == Z_RPNStructure_simple)
154 if (zs->u.simple->which == Z_Operand_APT)
155 return yaz_query2xml_apt(zs->u.simple->u.attributesPlusTerm,
157 else if (zs->u.simple->which == Z_Operand_resultSetId)
161 yaz_term_to_wrbuf(b, zs->u.simple->u.resultSetId,
162 strlen(zs->u.simple->u.resultSetId));
171 xmlNodePtr yaz_query2xml_rpn(const Z_RPNQuery *rpn, xmlNodePtr parent)
173 oident *attrset = oid_getentbyoid (rpn->attributeSetId);
174 if (attrset && attrset->value)
175 parent = xmlNewChild(parent, /*ns */ 0,
176 BAD_CAST "attrset", BAD_CAST attrset->desc);
177 return yaz_query2xml_rpnstructure(rpn->RPNStructure, parent);
180 xmlNodePtr yaz_query2xml_ccl(const Odr_oct *ccl, xmlNodePtr node)
185 xmlNodePtr yaz_query2xml_z3958(const Odr_oct *ccl, xmlNodePtr node)
190 xmlNodePtr yaz_query2xml_cql(const char *cql, xmlNodePtr node)
195 void yaz_query2xml(const Z_Query *q, void *docp_void)
197 xmlDocPtr *docp = (xmlDocPtr *) docp_void;
198 xmlNodePtr top_node, child_node = 0;
199 const char *type = 0;
204 top_node = xmlNewNode(0, BAD_CAST "query");
209 case Z_Query_type_101:
211 child_node = yaz_query2xml_rpn(q->u.type_1, top_node);
215 child_node = yaz_query2xml_ccl(q->u.type_2, top_node);
217 case Z_Query_type_100:
219 child_node = yaz_query2xml_z3958(q->u.type_100, top_node);
221 case Z_Query_type_104:
222 if (q->u.type_104->which == Z_External_CQL)
225 child_node = yaz_query2xml_cql(q->u.type_104->u.cql, top_node);
229 if (child_node && type)
231 *docp = xmlNewDoc(BAD_CAST "1.0");
232 xmlDocSetRootElement(*docp, top_node); /* make it top node in doc */
234 /* set type attribute now */
235 xmlNewProp(top_node, BAD_CAST "type", BAD_CAST type);
240 xmlFreeNode(top_node);
244 void yaz_xml2query(const xmlNode node, Z_Query **q, ODR odr)
257 * indent-tabs-mode: nil
259 * vim: shiftwidth=4 tabstop=8 expandtab