2 * Copyright (C) 2005-2006, Index Data ApS
3 * See the file LICENSE for details.
5 * $Id: record_conv.c,v 1.1 2006-05-02 20:47:45 adam Exp $
9 * \brief Record Conversions utility
17 #include <libxml/parser.h>
18 #include <libxml/tree.h>
23 #include <yaz/record_conv.h>
24 #include <yaz/wrbuf.h>
25 #include <yaz/xmalloc.h>
28 /** \brief The internal structure for yaz_record_conv_t */
29 struct yaz_record_conv_struct {
30 /** memory for configuration */
33 /** conversion rules (allocated using NMEM) */
34 struct yaz_record_conv_rule *rules;
36 /** pointer to last conversion rule pointer in chain */
37 struct yaz_record_conv_rule **rules_p;
39 /** string buffer for error messages */
43 /** \brief tranformation types (rule types) */
44 enum YAZ_RECORD_CONV_RULE
46 YAZ_RECORD_CONV_RULE_XSLT,
47 YAZ_RECORD_CONV_RULE_MARC_TO_XML,
48 YAZ_RECORD_CONV_RULE_XML_TO_MARC
51 /** \brief tranformation info (rule info) */
52 struct yaz_record_conv_rule {
53 enum YAZ_RECORD_CONV_RULE which;
56 const char *stylesheet;
65 struct yaz_record_conv_rule *next;
68 yaz_record_conv_t yaz_record_conv_create()
70 yaz_record_conv_t p = xmalloc(sizeof(*p));
71 p->nmem = nmem_create();
72 p->wr_error = wrbuf_alloc();
76 void yaz_record_conv_destroy(yaz_record_conv_t p)
80 nmem_destroy(p->nmem);
81 wrbuf_free(p->wr_error, 1);
87 static struct yaz_record_conv_rule *add_rule(yaz_record_conv_t p,
88 enum YAZ_RECORD_CONV_RULE type)
90 struct yaz_record_conv_rule *r = nmem_malloc(p->nmem, sizeof(*r));
94 p->rules_p = &r->next;
98 static void yaz_record_conv_reset(yaz_record_conv_t p)
100 wrbuf_rewind(p->wr_error);
103 p->rules_p = &p->rules;
106 static int conv_xslt(yaz_record_conv_t p, const xmlNode *ptr)
108 struct _xmlAttr *attr;
109 const char *stylesheet = 0;
111 for (attr = ptr->properties; attr; attr = attr->next)
113 if (!xmlStrcmp(attr->name, BAD_CAST "stylesheet") &&
114 attr->children && attr->children->type == XML_TEXT_NODE)
115 stylesheet = (const char *) attr->children->content;
118 wrbuf_printf(p->wr_error, "Bad attribute '%s'."
119 "Expected stylesheet.", attr->name);
125 struct yaz_record_conv_rule *r =
126 add_rule(p, YAZ_RECORD_CONV_RULE_XSLT);
127 r->u.xslt.stylesheet = nmem_strdup(p->nmem, stylesheet);
130 wrbuf_printf(p->wr_error, "Missing attribute 'stylesheet'");
134 static int conv_marc_to_xml(yaz_record_conv_t p, const xmlNode *ptr)
136 struct _xmlAttr *attr;
137 const char *charset = 0;
138 struct yaz_record_conv_rule *r;
140 for (attr = ptr->properties; attr; attr = attr->next)
142 if (!xmlStrcmp(attr->name, BAD_CAST "charset") &&
143 attr->children && attr->children->type == XML_TEXT_NODE)
144 charset = (const char *) attr->children->content;
147 wrbuf_printf(p->wr_error, "Bad attribute '%s'."
148 "Expected charset.", attr->name);
152 r = add_rule(p, YAZ_RECORD_CONV_RULE_MARC_TO_XML);
154 r->u.marc_to_xml.charset = nmem_strdup(p->nmem, charset);
156 r->u.marc_to_xml.charset = 0;
160 static int conv_xml_to_marc(yaz_record_conv_t p, const xmlNode *ptr)
162 struct _xmlAttr *attr;
163 const char *charset = 0;
164 struct yaz_record_conv_rule *r;
166 for (attr = ptr->properties; attr; attr = attr->next)
168 if (!xmlStrcmp(attr->name, BAD_CAST "charset") &&
169 attr->children && attr->children->type == XML_TEXT_NODE)
170 charset = (const char *) attr->children->content;
173 wrbuf_printf(p->wr_error, "Bad attribute '%s'."
174 "Expected charset.", attr->name);
178 r = add_rule(p, YAZ_RECORD_CONV_RULE_XML_TO_MARC);
180 r->u.xml_to_marc.charset = nmem_strdup(p->nmem, charset);
182 r->u.xml_to_marc.charset = 0;
187 int yaz_record_conv_configure(yaz_record_conv_t p, const void *ptr_v)
189 const xmlNode *ptr = ptr_v;
191 yaz_record_conv_reset(p);
193 if (ptr && ptr->type == XML_ELEMENT_NODE &&
194 !strcmp((const char *) ptr->name, "convert"))
196 for (ptr = ptr->children; ptr; ptr = ptr->next)
198 if (ptr->type != XML_ELEMENT_NODE)
200 if (!strcmp((const char *) ptr->name, "xslt"))
202 if (conv_xslt(p, ptr))
205 else if (!strcmp((const char *) ptr->name, "marc_to_xml"))
207 if (conv_marc_to_xml(p, ptr))
210 else if (!strcmp((const char *) ptr->name, "xml_to_marc"))
212 if (conv_xml_to_marc(p, ptr))
217 wrbuf_printf(p->wr_error, "Bad element '%s'."
218 "Expected xslt, marc_to_xml,...", ptr->name);
225 wrbuf_printf(p->wr_error, "Missing 'convert' element");
233 int yaz_record_conv_configure(yaz_record_conv_t p, const void *ptr_v)
235 wrbuf_rewind(p->wr_error);
236 wrbuf_printf(p->wr_error, "No XML support for yaz_record_conv");
242 const char *yaz_record_conv_get_error(yaz_record_conv_t p)
244 return wrbuf_buf(p->wr_error);
250 * indent-tabs-mode: nil
252 * vim: shiftwidth=4 tabstop=8 expandtab