Happy new year
[yaz-moved-to-github.git] / src / cclxmlconfig.c
1 /* This file is part of the YAZ toolkit.
2  * Copyright (C) 1995-2009 Index Data
3  * See the file LICENSE for details.
4  */
5
6 /** \file cclxmlconfig.c
7     \brief XML configuration for CCL
8 */
9
10 #include <stdio.h>
11 #include <string.h>
12 #include <assert.h>
13
14 #include <yaz/ccl_xml.h>
15
16 #if YAZ_HAVE_XML2
17
18 static int ccl_xml_config_attr(CCL_bibset bibset, const char *default_set,
19                                WRBUF wrbuf,
20                                const xmlNode *ptr,
21                                const char **addinfo)
22 {
23     struct _xmlAttr *attr;
24     const char *type = 0;
25     const char *value = 0;
26     const char *attrset = default_set;
27     for (attr = ptr->properties; attr; attr = attr->next)
28     {
29         if (!xmlStrcmp(attr->name, BAD_CAST "type") &&
30             attr->children && attr->children->type == XML_TEXT_NODE)
31             type = (const char *) attr->children->content;
32         else if (!xmlStrcmp(attr->name, BAD_CAST "value") &&
33             attr->children && attr->children->type == XML_TEXT_NODE)
34             value = (const char *) attr->children->content;
35         else if (!xmlStrcmp(attr->name, BAD_CAST "attrset") &&
36             attr->children && attr->children->type == XML_TEXT_NODE)
37             attrset = (const char *) attr->children->content;
38         else
39         {
40             *addinfo = "bad attribute for 'attr'. "
41                 "Expecting 'type', 'value', or 'attrset'";
42             return 1;
43         }
44     }
45     if (!type)
46     {
47         *addinfo = "missing attribute for 'type' for element 'attr'";
48         return 1;
49     }
50     if (!value)
51     {
52         *addinfo = "missing attribute for 'value' for element 'attr'";
53         return 1;
54     }
55     if (attrset)
56         wrbuf_printf(wrbuf, "%s,%s=%s", attrset, type, value);
57     else
58         wrbuf_printf(wrbuf, "%s=%s", type, value);
59     return 0;
60 }
61
62 static int ccl_xml_config_qual(CCL_bibset bibset, const char *default_set,
63                                WRBUF wrbuf, 
64                                const xmlNode *ptr,
65                                const char **addinfo)
66 {
67     struct _xmlAttr *attr;
68     const char *name = 0;
69     const xmlNode *a_ptr = ptr->children;
70     for (attr = ptr->properties; attr; attr = attr->next)
71     {
72         if (!xmlStrcmp(attr->name, BAD_CAST "name") &&
73             attr->children && attr->children->type == XML_TEXT_NODE)
74             name = (const char *) attr->children->content;
75         else
76         {
77             *addinfo = "bad attribute for 'qual'. Expecting 'name' only";
78             return 1;
79         }
80     }
81     if (!name)
82     {
83         *addinfo = "missing attribute 'name' for 'qual' element";
84         return 1;
85     }
86     for (; a_ptr; a_ptr = a_ptr->next)
87     {
88         if (a_ptr->type == XML_ELEMENT_NODE)
89         {
90             if (!xmlStrcmp(a_ptr->name, BAD_CAST "attr"))
91             {
92                 int r = ccl_xml_config_attr(bibset, default_set, wrbuf,
93                                             a_ptr, addinfo);
94                 if (r)
95                     return r;
96                 wrbuf_printf(wrbuf, " ");
97             }
98             else
99             {
100                 *addinfo = "bad element: expecting 'attr'";
101                 return 1;
102             }
103         }
104     }
105     ccl_qual_fitem(bibset, wrbuf_cstr(wrbuf), name);
106     return 0;
107 }
108
109 int ccl_xml_config_directive(CCL_bibset bibset, const xmlNode *ptr,
110                              const char **addinfo)
111 {
112     struct _xmlAttr *attr;
113     const char *name = 0;
114     const char *value = 0;
115     for (attr = ptr->properties; attr; attr = attr->next)
116     {
117         if (!xmlStrcmp(attr->name, BAD_CAST "name") &&
118             attr->children && attr->children->type == XML_TEXT_NODE)
119             name = (const char *) attr->children->content;
120         else if (!xmlStrcmp(attr->name, BAD_CAST "value") &&
121             attr->children && attr->children->type == XML_TEXT_NODE)
122             value = (const char *) attr->children->content;
123         else
124         {
125             *addinfo = "bad attribute for 'diretive'. "
126                 "Expecting 'name' or 'value'";
127             return 1;
128         }
129     }
130     if (!name)
131     {
132         *addinfo = "missing attribute 'name' for 'directive' element";
133         return 1;
134     }
135     if (!value)
136     {
137         *addinfo = "missing attribute 'name' for 'value' element";
138         return 1;
139     }
140     ccl_qual_add_special(bibset, name, value);
141     return 0;
142 }
143
144 int ccl_xml_config(CCL_bibset bibset, const xmlNode *ptr, const char **addinfo)
145 {
146     if (ptr && ptr->type == XML_ELEMENT_NODE && 
147         !xmlStrcmp(ptr->name, BAD_CAST "cclmap"))
148     {
149         const xmlNode *c_ptr;
150         const char *set = 0;
151         struct _xmlAttr *attr;
152         for (attr = ptr->properties; attr; attr = attr->next)
153         {
154             if (!xmlStrcmp(attr->name, BAD_CAST "defaultattrset") &&
155                 attr->children && attr->children->type == XML_TEXT_NODE)
156                 set = (const char *) attr->children->content;
157             else
158             {
159                 *addinfo = "bad attribute for 'cclmap'. "
160                     "expecting 'defaultattrset'";
161                 return 1;
162             }
163         }
164         for (c_ptr = ptr->children; c_ptr; c_ptr = c_ptr->next)
165         {
166             if (c_ptr->type == XML_ELEMENT_NODE)
167             {
168                 if (!xmlStrcmp(c_ptr->name, BAD_CAST "qual"))
169                 {
170                     WRBUF wrbuf = wrbuf_alloc();
171                     int r = ccl_xml_config_qual(bibset, set,
172                                                 wrbuf, c_ptr, addinfo);
173                     wrbuf_destroy(wrbuf);
174                     if (r)
175                         return r;
176                 }
177                 else if (!xmlStrcmp(c_ptr->name, BAD_CAST "directive"))
178                 {
179                     int r = ccl_xml_config_directive(bibset, c_ptr, addinfo);
180                     if (r)
181                         return r;
182                 }
183                 else
184                 {
185                     *addinfo = "bad element for 'cclmap'. "
186                         "expecting 'directive' or 'qual'";
187                     return 1;
188                 }
189             }
190         }
191     }
192     return 0;
193 }
194 #endif
195
196 /*
197  * Local variables:
198  * c-basic-offset: 4
199  * indent-tabs-mode: nil
200  * End:
201  * vim: shiftwidth=4 tabstop=8 expandtab
202  */