gwenhywfar  4.99.8beta
xml2db.c
Go to the documentation of this file.
1 /***************************************************************************
2  begin : Sun Dec 16 2018
3  copyright : (C) 2018 by Martin Preuss
4  email : martin@libchipcard.de
5 
6  ***************************************************************************
7  * *
8  * This library is free software; you can redistribute it and/or *
9  * modify it under the terms of the GNU Lesser General Public *
10  * License as published by the Free Software Foundation; either *
11  * version 2.1 of the License, or (at your option) any later version. *
12  * *
13  * This library is distributed in the hope that it will be useful, *
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
16  * Lesser General Public License for more details. *
17  * *
18  * You should have received a copy of the GNU Lesser General Public *
19  * License along with this library; if not, write to the Free Software *
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, *
21  * MA 02111-1307 USA *
22  * *
23  ***************************************************************************/
24 
25 
26 #ifdef HAVE_CONFIG_H
27 # include <config.h>
28 #endif
29 
30 
31 
32 #include "xml2db_p.h"
33 
34 #include <gwenhywfar/debug.h>
35 #include <gwenhywfar/text.h>
36 #include <gwenhywfar/gwendate.h>
37 
38 
39 #include <ctype.h>
40 
41 
42 
43 GWEN_XML2DB_CONTEXT *GWEN_Xml2Db_Context_new(GWEN_XMLNODE *documentRoot, GWEN_DB_NODE *dbRoot) {
44  GWEN_XML2DB_CONTEXT *ctx;
45 
46  GWEN_NEW_OBJECT(GWEN_XML2DB_CONTEXT, ctx);
47  assert(ctx);
48 
49  ctx->docRoot=documentRoot;
50  ctx->xmlNodeStack=GWEN_XMLNode_List2_new();
51  ctx->dbRoot=dbRoot;
52  ctx->tempDbRoot=GWEN_DB_Group_new("dbTempRoot");
53 
54  ctx->currentDbGroup=ctx->dbRoot;
55  ctx->currentTempDbGroup=ctx->tempDbRoot;
56  ctx->currentDocNode=documentRoot;
57 
58  return ctx;
59 }
60 
61 
62 
63 void GWEN_Xml2Db_Context_free(GWEN_XML2DB_CONTEXT *ctx) {
64  if (ctx) {
65  GWEN_XMLNode_List2_free(ctx->xmlNodeStack);
66  ctx->xmlNodeStack=NULL;
67 
68  GWEN_DB_Group_free(ctx->tempDbRoot);
69  GWEN_FREE_OBJECT(ctx);
70  }
71 }
72 
73 
74 
75 void GWEN_Xml2Db_Context_EnterDocNode(GWEN_XML2DB_CONTEXT *ctx, GWEN_XMLNODE *xmlNode) {
76  assert(ctx);
77  assert(xmlNode);
78 
79  GWEN_XMLNode_List2_PushBack(ctx->xmlNodeStack, ctx->currentDocNode);
80  ctx->currentDocNode=xmlNode;
81 }
82 
83 
84 
85 void GWEN_Xml2Db_Context_LeaveDocNode(GWEN_XML2DB_CONTEXT *ctx) {
86  GWEN_XMLNODE *xmlNode;
87 
88  assert(ctx);
89 
90  xmlNode=GWEN_XMLNode_List2_GetBack(ctx->xmlNodeStack);
91  if (xmlNode==NULL) {
92  DBG_ERROR(GWEN_LOGDOMAIN, "Nothing on stack");
93  assert(xmlNode);
94  }
95  ctx->currentDocNode=xmlNode;
96  GWEN_XMLNode_List2_PopBack(ctx->xmlNodeStack);
97 }
98 
99 
100 
101 
102 
103 
104 const char *GWEN_Xml2Db_GetCharValueByPath(GWEN_XMLNODE *xmlNode, const char *path, const char *defValue) {
105  const char *s;
106 
107  s=strchr(path, '@');
108  if (s) {
109  int idx;
110  char *cpyOfPath;
111  char *property;
112  GWEN_XMLNODE *n;
113 
114 
115  idx=s-path;
116  cpyOfPath=strdup(path);
117  assert(cpyOfPath);
118  cpyOfPath[idx]=0;
119  property=cpyOfPath+idx+1;
120 
121  if (*cpyOfPath) {
123  }
124  else
125  n=xmlNode;
126 
127  if (n) {
128  const char *result;
129 
130  result=GWEN_XMLNode_GetProperty(n, property, defValue);
131  DBG_INFO(GWEN_LOGDOMAIN, "Got XML property: %s = %s (%s)", property, result, path);
132  free(cpyOfPath);
133  return result;
134  }
135  free(cpyOfPath);
136  return defValue;
137  }
138  else
139  return GWEN_XMLNode_GetCharValueByPath(xmlNode, path, defValue);
140 }
141 
142 
143 /* TODO: optimize later */
144 int GWEN_Xml2Db_ConvertAndSetCharValue(GWEN_XML2DB_CONTEXT *ctx, GWEN_XMLNODE *xmlNode, GWEN_DB_NODE *dbCurrent, const char *value) {
145  if (value && *value) {
146  const char *name;
147  const char *typ;
148  const char *mode;
149  int doTrim=0;
150  GWEN_BUFFER *vbuf;
151  GWEN_BUFFER *resultBuf;
152 
153  doTrim=GWEN_XMLNode_GetIntProperty(xmlNode, "trim", 0);
154  vbuf=GWEN_Buffer_new(0, 256, 0, 1);
155  resultBuf=GWEN_Buffer_new(0, 256, 0, 1);
156 
157  name=GWEN_XMLNode_GetProperty(xmlNode, "name", NULL);
158  if (!(name && *name)) {
159  DBG_ERROR(GWEN_LOGDOMAIN, "Missing or empty name in \"SetCharValue\"");
160  GWEN_Buffer_free(resultBuf);
161  GWEN_Buffer_free(vbuf);
162  return GWEN_ERROR_INVALID;
163  }
164 
165  typ=GWEN_XMLNode_GetProperty(xmlNode, "type", "string");
166  if (!(typ && *typ)) {
167  DBG_ERROR(GWEN_LOGDOMAIN, "Empty type in \"SetCharValue\"");
168  GWEN_Buffer_free(resultBuf);
169  GWEN_Buffer_free(vbuf);
170  return GWEN_ERROR_INVALID;
171  }
172 
173  mode=GWEN_XMLNode_GetProperty(xmlNode, "mode", "add");
174 
175  if (strcasecmp(typ, "string")==0) {
176  GWEN_Buffer_AppendString(vbuf, value);
177  if (doTrim)
179  }
180  else if (strcasecmp(typ, "date")==0) {
181  const char *tmpl;
182  GWEN_DATE *dt=NULL;
183 
184  tmpl=GWEN_XMLNode_GetProperty(xmlNode, "template", "YYYYMMDD");
185  if (!(tmpl && *tmpl)) {
186  DBG_ERROR(GWEN_LOGDOMAIN, "Empty template in \"SetCharValue\"");
187  GWEN_Buffer_free(resultBuf);
188  GWEN_Buffer_free(vbuf);
189  return GWEN_ERROR_INVALID;
190  }
191 
192  dt=GWEN_Date_fromStringWithTemplate(value, tmpl);
193  if (dt) {
195  GWEN_Date_free(dt);
196  }
197  }
198 
199  if (strcasecmp(mode, "add")==0) {
200  /* just exchange the buffer */
201  GWEN_Buffer_free(resultBuf);
202  resultBuf=vbuf;
203  vbuf=NULL;
204  }
205  else if (strcasecmp(mode, "append")==0) {
206  const char *s;
207 
208  s=GWEN_DB_GetCharValue(dbCurrent, name, 0, NULL);
209  if (s && *s) {
210  const char *delimiter;
211 
212  /* write previous data into resultBuffer */
213  GWEN_Buffer_AppendString(resultBuf, s);
214 
215  /* possibly write delimiter into resultBuffer */
216  delimiter=GWEN_XMLNode_GetProperty(xmlNode, "delimiter", NULL);
217  if (delimiter && *delimiter) {
218  if (strcasecmp(delimiter, "\\n")==0)
219  GWEN_Buffer_AppendByte(resultBuf, '\n');
220  else if (strcasecmp(delimiter, "\\t")==0)
221  GWEN_Buffer_AppendByte(resultBuf, '\t');
222  else
223  GWEN_Buffer_AppendString(resultBuf, delimiter);
224  }
225  } /* if previous value */
226  /* write value into resultBuffer */
228 
229  GWEN_DB_DeleteVar(dbCurrent, name);
230  }
231  else if (strcasecmp(mode, "replace")==0) {
232  /* just exchange the buffer */
233  GWEN_Buffer_free(resultBuf);
234  resultBuf=vbuf;
235  vbuf=NULL;
236  GWEN_DB_DeleteVar(dbCurrent, name);
237  }
238 
239  DBG_INFO(GWEN_LOGDOMAIN, "Setting value: %s = %s", name, GWEN_Buffer_GetStart(resultBuf));
240 
242  GWEN_Buffer_free(resultBuf);
243  GWEN_Buffer_free(vbuf);
244  }
245  return 0;
246 }
247 
248 
249 
250 
251 
252 
253 
254 int GWEN_Xml2Db_Handle_XmlEnter(GWEN_XML2DB_CONTEXT *ctx, GWEN_XMLNODE *xmlNode) {
255  const char *path;
256  GWEN_XMLNODE *n;
257  int rv;
258 
259  path=GWEN_XMLNode_GetProperty(xmlNode, "path", NULL);
260  if (path==NULL) {
261  DBG_ERROR(GWEN_LOGDOMAIN, "Missing path in \"EnterPath\"");
262  return GWEN_ERROR_INVALID;
263  }
264 
265  n=GWEN_XMLNode_GetNodeByXPath(ctx->currentDocNode, path, GWEN_PATH_FLAGS_PATHMUSTEXIST);
266  if (n==NULL) {
267  DBG_ERROR(GWEN_LOGDOMAIN, "Path \"%s\" does not exist", path);
268  return GWEN_ERROR_INVALID;
269  }
270 
271  /* enter given document node */
273 
274  rv=GWEN_Xml2Db_HandleChildren(ctx, xmlNode);
275  if (rv<0) {
276  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
277  return rv;
278  }
279 
280  /* leave given document node, re-select previously active one, thus restoring status from the beginning */
282  return 0;
283 }
284 
285 
286 
287 int GWEN_Xml2Db_Handle_XmlForEvery(GWEN_XML2DB_CONTEXT *ctx, GWEN_XMLNODE *xmlNode) {
288  const char *path;
289  GWEN_XMLNODE *n;
290  int rv;
291 
292  path=GWEN_XMLNode_GetProperty(xmlNode, "name", NULL);
293  if (path==NULL) {
294  DBG_ERROR(GWEN_LOGDOMAIN, "Missing name in \"ForEvery\"");
295  return GWEN_ERROR_INVALID;
296  }
297 
298  n=GWEN_XMLNode_FindFirstTag(ctx->currentDocNode, path, NULL, NULL);
299  if (n==NULL) {
300  DBG_ERROR(GWEN_LOGDOMAIN, "Path \"%s\" not found", path);
301  /* GWEN_XMLNode_Dump(ctx->currentDocNode, 2); */
302  }
303  while (n){
304 
305  /* enter given document node */
307 
308  /* handle all children of this parser XML node with the current document node */
309  rv=GWEN_Xml2Db_HandleChildren(ctx, xmlNode);
310 
311  /* leave given document node, re-select previously active one, thus restoring status from the beginning */
313 
314  if (rv<0) {
315  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
316  return rv;
317  }
318 
319  n=GWEN_XMLNode_FindNextTag(n, path, NULL, NULL);
320  }
321 
322  return 0;
323 }
324 
325 
326 
327 int GWEN_Xml2Db_Handle_DbCreateAndEnterGroup(GWEN_XML2DB_CONTEXT *ctx, GWEN_XMLNODE *xmlNode) {
328  const char *name;
329  GWEN_DB_NODE *dbLast;
330  int rv;
331 
332  name=GWEN_XMLNode_GetProperty(xmlNode, "name", NULL);
333  if (!(name && *name)) {
334  DBG_ERROR(GWEN_LOGDOMAIN, "Missing or empty name in \"CreateAnEnterDbGroup\"");
335  return GWEN_ERROR_INVALID;
336  }
337 
338  /* push group */
339  dbLast=ctx->currentDbGroup;
340 
341  /* create group */
342  ctx->currentDbGroup=GWEN_DB_GetGroup(dbLast, GWEN_PATH_FLAGS_CREATE_GROUP, name);
343 
344  /* handle children (nothing special here) */
345  rv=GWEN_Xml2Db_HandleChildren(ctx, xmlNode);
346 
347  /* pop group */
348  ctx->currentDbGroup=dbLast;
349 
350  if (rv<0) {
351  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
352  return rv;
353  }
354 
355  return 0;
356 }
357 
358 
359 
360 int GWEN_Xml2Db_Handle_DbCreateAndEnterTempGroup(GWEN_XML2DB_CONTEXT *ctx, GWEN_XMLNODE *xmlNode) {
361  const char *name;
362  GWEN_DB_NODE *dbLast;
363  int rv;
364 
365  name=GWEN_XMLNode_GetProperty(xmlNode, "name", NULL);
366  if (!(name && *name)) {
367  DBG_ERROR(GWEN_LOGDOMAIN, "Missing or empty name in \"CreateAnEnterTempDbGroup\"");
368  return GWEN_ERROR_INVALID;
369  }
370 
371  /* push group */
372  dbLast=ctx->currentTempDbGroup;
373 
374  /* create group */
375  ctx->currentTempDbGroup=GWEN_DB_GetGroup(dbLast, GWEN_PATH_FLAGS_CREATE_GROUP, name);
376  assert(ctx->currentTempDbGroup);
377 
378  /* handle children (nothing special here) */
379  rv=GWEN_Xml2Db_HandleChildren(ctx, xmlNode);
380 
381  /* delete temp group */
382  GWEN_DB_UnlinkGroup(ctx->currentTempDbGroup);
383  GWEN_DB_Group_free(ctx->currentTempDbGroup);
384 
385  /* pop group */
386  ctx->currentTempDbGroup=dbLast;
387 
388  if (rv<0) {
389  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
390  return rv;
391  }
392 
393  return 0;
394 }
395 
396 
397 
398 int GWEN_Xml2Db_Handle_DbSetCharValue_internal(GWEN_XML2DB_CONTEXT *ctx, GWEN_XMLNODE *xmlNode, GWEN_DB_NODE *dbCurrent) {
399  const char *name;
400  const char *value;
401 
402  name=GWEN_XMLNode_GetProperty(xmlNode, "name", NULL);
403  if (!(name && *name)) {
404  DBG_ERROR(GWEN_LOGDOMAIN, "Missing or empty name in \"SetCharValue\"");
405  return GWEN_ERROR_INVALID;
406  }
407 
408  value=GWEN_XMLNode_GetProperty(xmlNode, "value", NULL);
409  if (value) {
410  GWEN_BUFFER *dbuf;
411  int rv;
412 
413  dbuf=GWEN_Buffer_new(0, 256, 0, 1);
414  rv=GWEN_DB_ReplaceVars(ctx->currentTempDbGroup, value, dbuf);
415  if (rv<0) {
416  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
417  GWEN_Buffer_free(dbuf);
418  return rv;
419  }
420  GWEN_Xml2Db_ConvertAndSetCharValue(ctx, xmlNode, dbCurrent, GWEN_Buffer_GetStart(dbuf));
421  GWEN_Buffer_free(dbuf);
422  }
423  else {
424  const char *path;
425 
426  path=GWEN_XMLNode_GetProperty(xmlNode, "path", NULL);
427  if (!(path && *path)) {
428  DBG_ERROR(GWEN_LOGDOMAIN, "Missing or empty path in \"SetCharValue\"");
429  return GWEN_ERROR_INVALID;
430  }
431 
432  value=GWEN_Xml2Db_GetCharValueByPath(ctx->currentDocNode, path, NULL);
433  if (value && *value) {
434  GWEN_Xml2Db_ConvertAndSetCharValue(ctx, xmlNode, dbCurrent, value);
435  }
436  else {
437  GWEN_BUFFER *tbuf;
438 
439  tbuf=GWEN_Buffer_new(0, 256, 0, 1);
440 
441  GWEN_XMLNode_GetXPath(NULL, ctx->currentDocNode, tbuf);
442 
443  DBG_ERROR(GWEN_LOGDOMAIN, "No value in path \"%s\" (%s)", path, GWEN_Buffer_GetStart(tbuf));
444  GWEN_Buffer_free(tbuf);
445 
446  /* GWEN_XMLNode_Dump(ctx->currentDocNode, 2); */
447  }
448  }
449 
450  return 0;
451 }
452 
453 
454 
455 int GWEN_Xml2Db_Handle_DbSetCharValue(GWEN_XML2DB_CONTEXT *ctx, GWEN_XMLNODE *xmlNode) {
456  return GWEN_Xml2Db_Handle_DbSetCharValue_internal(ctx, xmlNode, ctx->currentDbGroup);
457 }
458 
459 
460 
461 int GWEN_Xml2Db_Handle_DbSetTempCharValue(GWEN_XML2DB_CONTEXT *ctx, GWEN_XMLNODE *xmlNode) {
462  return GWEN_Xml2Db_Handle_DbSetCharValue_internal(ctx, xmlNode, ctx->currentTempDbGroup);
463 }
464 
465 
466 
467 int GWEN_Xml2Db_Handle_XmlIfCharDataMatches(GWEN_XML2DB_CONTEXT *ctx, GWEN_XMLNODE *xmlNode) {
468  const char *pattern;
469  const char *path;
470  const char *value;
471 
472  path=GWEN_XMLNode_GetProperty(xmlNode, "path", NULL);
473  if (!(path && *path)) {
474  DBG_ERROR(GWEN_LOGDOMAIN, "Missing or empty path in \"IfCharDataMatches\"");
475  return GWEN_ERROR_INVALID;
476  }
477 
478  pattern=GWEN_XMLNode_GetProperty(xmlNode, "pattern", NULL);
479  if (!(pattern && *pattern)) {
480  DBG_ERROR(GWEN_LOGDOMAIN, "Missing or empty pattern in \"IfCharDataMatches\"");
481  return GWEN_ERROR_INVALID;
482  }
483 
484  value=GWEN_Xml2Db_GetCharValueByPath(ctx->currentDocNode, path, NULL);
485  if (value) {
486  if (-1!=GWEN_Text_ComparePattern(value, pattern, 0)) {
487  int rv;
488 
489  /* pattern matches, handle children */
490  rv=GWEN_Xml2Db_HandleChildren(ctx, xmlNode);
491  if (rv<0) {
492  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
493  return rv;
494  }
495  }
496  }
497 
498  return 0;
499 }
500 
501 
502 
503 int GWEN_Xml2Db_Handle_XmlIfNotCharDataMatches(GWEN_XML2DB_CONTEXT *ctx, GWEN_XMLNODE *xmlNode) {
504  const char *pattern;
505  const char *path;
506  const char *value;
507 
508  path=GWEN_XMLNode_GetProperty(xmlNode, "path", NULL);
509  if (!(path && *path)) {
510  DBG_ERROR(GWEN_LOGDOMAIN, "Missing or empty path in \"IfNotCharDataMatches\"");
511  return GWEN_ERROR_INVALID;
512  }
513 
514  pattern=GWEN_XMLNode_GetProperty(xmlNode, "pattern", NULL);
515  if (!(pattern && *pattern)) {
516  DBG_ERROR(GWEN_LOGDOMAIN, "Missing or empty pattern in \"IfNotCharDataMatches\"");
517  return GWEN_ERROR_INVALID;
518  }
519 
520  value=GWEN_Xml2Db_GetCharValueByPath(ctx->currentDocNode, path, NULL);
521  if (value) {
522  if (-1==GWEN_Text_ComparePattern(value, pattern, 0)) {
523  int rv;
524 
525  /* pattern doesnt match, handle children */
526  rv=GWEN_Xml2Db_HandleChildren(ctx, xmlNode);
527  if (rv<0) {
528  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
529  return rv;
530  }
531  }
532  }
533 
534  return 0;
535 }
536 
537 
538 
539 int GWEN_Xml2Db_Handle_XmlIfHasCharData(GWEN_XML2DB_CONTEXT *ctx, GWEN_XMLNODE *xmlNode) {
540  const char *path;
541  const char *value;
542 
543  path=GWEN_XMLNode_GetProperty(xmlNode, "path", NULL);
544  if (!(path && *path)) {
545  DBG_ERROR(GWEN_LOGDOMAIN, "Missing or empty path in \"IfCharDataMatches\"");
546  return GWEN_ERROR_INVALID;
547  }
548 
549  value=GWEN_Xml2Db_GetCharValueByPath(ctx->currentDocNode, path, NULL);
550  if (value && *value) {
551  int rv;
552 
553  /* there is a value, handle children */
554  rv=GWEN_Xml2Db_HandleChildren(ctx, xmlNode);
555  if (rv<0) {
556  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
557  return rv;
558  }
559  }
560  else {
561  DBG_INFO(GWEN_LOGDOMAIN, "No value for path \"%s\"", path);
562  }
563 
564  return 0;
565 }
566 
567 
568 
569 int GWEN_Xml2Db_Handle_XmlIfNotHasCharData(GWEN_XML2DB_CONTEXT *ctx, GWEN_XMLNODE *xmlNode) {
570  const char *path;
571  const char *value;
572 
573  path=GWEN_XMLNode_GetProperty(xmlNode, "path", NULL);
574  if (!(path && *path)) {
575  DBG_ERROR(GWEN_LOGDOMAIN, "Missing or empty path in \"IfNotCharDataMatches\"");
576  return GWEN_ERROR_INVALID;
577  }
578 
579  value=GWEN_Xml2Db_GetCharValueByPath(ctx->currentDocNode, path, NULL);
580  if (!(value && *value)) {
581  int rv;
582 
583  /* there is a value, handle children */
584  rv=GWEN_Xml2Db_HandleChildren(ctx, xmlNode);
585  if (rv<0) {
586  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
587  return rv;
588  }
589  }
590 
591  return 0;
592 }
593 
594 
595 
596 int GWEN_Xml2Db_Handle_XmlIfPathExists(GWEN_XML2DB_CONTEXT *ctx, GWEN_XMLNODE *xmlNode) {
597  const char *path;
598 
599  path=GWEN_XMLNode_GetProperty(xmlNode, "path", NULL);
600  if (!(path && *path)) {
601  DBG_ERROR(GWEN_LOGDOMAIN, "Missing or empty path in \"IfPathExists\"");
602  return GWEN_ERROR_INVALID;
603  }
604 
605  if (GWEN_XMLNode_GetNodeByXPath(ctx->currentDocNode, path, GWEN_PATH_FLAGS_PATHMUSTEXIST)) {
606  int rv;
607 
608  /* path exists, handle children */
609  rv=GWEN_Xml2Db_HandleChildren(ctx, xmlNode);
610  if (rv<0) {
611  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
612  return rv;
613  }
614  }
615  else {
616  DBG_INFO(GWEN_LOGDOMAIN, "Path \"%s\" does not exist", path);
617  }
618 
619  return 0;
620 }
621 
622 
623 
624 int GWEN_Xml2Db_Handle_XmlIfNotPathExists(GWEN_XML2DB_CONTEXT *ctx, GWEN_XMLNODE *xmlNode) {
625  const char *path;
626 
627  path=GWEN_XMLNode_GetProperty(xmlNode, "path", NULL);
628  if (!(path && *path)) {
629  DBG_ERROR(GWEN_LOGDOMAIN, "Missing or empty path in \"IfNotPathExists\"");
630  return GWEN_ERROR_INVALID;
631  }
632 
633  if (NULL==GWEN_XMLNode_GetNodeByXPath(ctx->currentDocNode, path, GWEN_PATH_FLAGS_PATHMUSTEXIST)) {
634  int rv;
635 
636  /* path does not exist, handle children */
637  rv=GWEN_Xml2Db_HandleChildren(ctx, xmlNode);
638  if (rv<0) {
639  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
640  return rv;
641  }
642  }
643  else {
644  DBG_INFO(GWEN_LOGDOMAIN, "Path \"%s\" exists", path);
645  }
646 
647  return 0;
648 }
649 
650 
651 
652 
653 int GWEN_Xml2Db_HandleChildren(GWEN_XML2DB_CONTEXT *ctx, GWEN_XMLNODE *xmlNode) {
654  GWEN_XMLNODE *n;
655 
656  n=GWEN_XMLNode_GetFirstTag(xmlNode);
657  while(n) {
658  const char *name;
659 
660  name=GWEN_XMLNode_GetData(n);
661  if (name && *name) {
662  int rv;
663 
664  DBG_INFO(GWEN_LOGDOMAIN, "Handling element \"%s\"", name);
665  if (strcasecmp(name, "XmlEnter")==0)
666  rv=GWEN_Xml2Db_Handle_XmlEnter(ctx, n);
667  else if (strcasecmp(name, "XmlForEvery")==0)
669  else if (strcasecmp(name, "DbCreateAndEnterGroup")==0)
671  else if (strcasecmp(name, "DbCreateAndEnterTempGroup")==0)
673  else if (strcasecmp(name, "DbSetCharValue")==0)
675  else if (strcasecmp(name, "DbSetTempCharValue")==0)
677  else if (strcasecmp(name, "XmlIfCharDataMatches")==0)
679  else if (strcasecmp(name, "XmlIfNotCharDataMatches")==0)
681  else if (strcasecmp(name, "XmlIfHasCharData")==0)
683  else if (strcasecmp(name, "XmlIfNotHasCharData")==0)
685  else if (strcasecmp(name, "XmlIfPathExists")==0)
687  else if (strcasecmp(name, "XmlIfNotPathExists")==0)
689  else {
690  DBG_ERROR(GWEN_LOGDOMAIN, "Unknown element \"%s\", aborting", name);
691  return GWEN_ERROR_INVALID;
692  }
693  if (rv<0) {
694  DBG_ERROR(GWEN_LOGDOMAIN, "Error in element \"%s\", aborting", name);
695  return rv;
696  }
697  }
698 
700  }
701 
702  return 0;
703 }
704 
705 
706 
707 
708 int GWEN_Xml2Db(GWEN_XMLNODE *xmlNodeDocument,
709  GWEN_XMLNODE *xmlNodeSchema,
710  GWEN_DB_NODE *dbDestination) {
711  GWEN_XML2DB_CONTEXT *ctx;
712  int rv;
713 
714  ctx=GWEN_Xml2Db_Context_new(xmlNodeDocument, dbDestination);
715  rv=GWEN_Xml2Db_HandleChildren(ctx, xmlNodeSchema);
717 
718  if (rv<0) {
719  DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
720  return rv;
721  }
722 
723  return 0;
724 }
725 
726 
727 
GWEN_XML2DB_CONTEXT * GWEN_Xml2Db_Context_new(GWEN_XMLNODE *documentRoot, GWEN_DB_NODE *dbRoot)
Definition: xml2db.c:43
int GWEN_DB_ReplaceVars(GWEN_DB_NODE *db, const char *s, GWEN_BUFFER *dbuf)
Definition: db.c:1799
int GWEN_Xml2Db_Handle_XmlForEvery(GWEN_XML2DB_CONTEXT *ctx, GWEN_XMLNODE *xmlNode)
Definition: xml2db.c:287
char * GWEN_Buffer_GetStart(const GWEN_BUFFER *bf)
Definition: buffer.c:223
void GWEN_Text_CondenseBuffer(GWEN_BUFFER *buf)
Definition: text.c:1564
GWEN_DATE * GWEN_Date_fromStringWithTemplate(const char *s, const char *tmpl)
Definition: gwendate.c:338
struct GWEN_DB_NODE GWEN_DB_NODE
Definition: db.h:228
void GWEN_DB_Group_free(GWEN_DB_NODE *n)
Definition: db.c:369
#define GWEN_ERROR_INVALID
Definition: error.h:67
const char * GWEN_XMLNode_GetProperty(const GWEN_XMLNODE *n, const char *name, const char *defaultValue)
Definition: xml.c:228
GWEN_XMLNODE * GWEN_XMLNode_FindNextTag(const GWEN_XMLNODE *n, const char *tname, const char *pname, const char *pvalue)
Definition: xml.c:712
int GWEN_Xml2Db_Handle_XmlIfHasCharData(GWEN_XML2DB_CONTEXT *ctx, GWEN_XMLNODE *xmlNode)
Definition: xml2db.c:539
GWEN_XMLNODE_LIST2 * GWEN_XMLNode_List2_new()
void GWEN_Xml2Db_Context_EnterDocNode(GWEN_XML2DB_CONTEXT *ctx, GWEN_XMLNODE *xmlNode)
Definition: xml2db.c:75
#define GWEN_FREE_OBJECT(varname)
Definition: memory.h:92
#define NULL
Definition: binreloc.c:290
#define GWEN_PATH_FLAGS_CREATE_GROUP
Definition: path.h:96
int GWEN_Xml2Db_Handle_XmlIfNotCharDataMatches(GWEN_XML2DB_CONTEXT *ctx, GWEN_XMLNODE *xmlNode)
Definition: xml2db.c:503
int GWEN_Xml2Db_Handle_DbSetTempCharValue(GWEN_XML2DB_CONTEXT *ctx, GWEN_XMLNODE *xmlNode)
Definition: xml2db.c:461
void GWEN_XMLNode_List2_free(GWEN_XMLNODE_LIST2 *l)
#define GWEN_LOGDOMAIN
Definition: logger.h:35
GWEN_BUFFER * GWEN_Buffer_new(char *buffer, uint32_t size, uint32_t used, int take)
Definition: buffer.c:38
int GWEN_Xml2Db_Handle_XmlIfPathExists(GWEN_XML2DB_CONTEXT *ctx, GWEN_XMLNODE *xmlNode)
Definition: xml2db.c:596
GWEN_XMLNODE * GWEN_XMLNode_FindFirstTag(const GWEN_XMLNODE *n, const char *tname, const char *pname, const char *pvalue)
Definition: xml.c:695
#define GWEN_NEW_OBJECT(typ, varname)
Definition: memory.h:86
int GWEN_XMLNode_GetIntProperty(const GWEN_XMLNODE *n, const char *name, int defaultValue)
Definition: xml.c:251
void GWEN_Xml2Db_Context_free(GWEN_XML2DB_CONTEXT *ctx)
Definition: xml2db.c:63
const char * GWEN_Xml2Db_GetCharValueByPath(GWEN_XMLNODE *xmlNode, const char *path, const char *defValue)
Definition: xml2db.c:104
GWEN_XMLNODE * GWEN_XMLNode_GetNextTag(const GWEN_XMLNODE *n)
Definition: xml.c:635
void GWEN_XMLNode_List2_PopBack(GWEN_XMLNODE_LIST2 *l)
int GWEN_Xml2Db(GWEN_XMLNODE *xmlNodeDocument, GWEN_XMLNODE *xmlNodeSchema, GWEN_DB_NODE *dbDestination)
Definition: xml2db.c:708
void GWEN_Date_free(GWEN_DATE *gd)
Definition: gwendate.c:211
GWEN_XMLNODE * GWEN_XMLNode_GetNodeByXPath(GWEN_XMLNODE *n, const char *path, uint32_t flags)
Definition: xml.c:1212
int GWEN_Buffer_AppendByte(GWEN_BUFFER *bf, char c)
Definition: buffer.c:380
const char * GWEN_DB_GetCharValue(GWEN_DB_NODE *n, const char *path, int idx, const char *defVal)
Definition: db.c:897
GWEN_DB_NODE * GWEN_DB_GetGroup(GWEN_DB_NODE *n, uint32_t flags, const char *path)
Definition: db.c:1260
void GWEN_Buffer_free(GWEN_BUFFER *bf)
Definition: buffer.c:83
int GWEN_DB_DeleteVar(GWEN_DB_NODE *n, const char *path)
Definition: db.c:828
struct GWEN_BUFFER GWEN_BUFFER
A dynamically resizeable text buffer.
Definition: buffer.h:41
int GWEN_Xml2Db_Handle_XmlIfNotHasCharData(GWEN_XML2DB_CONTEXT *ctx, GWEN_XMLNODE *xmlNode)
Definition: xml2db.c:569
const char * GWEN_Date_GetString(const GWEN_DATE *gd)
Definition: gwendate.c:288
int GWEN_XMLNode_GetXPath(const GWEN_XMLNODE *n1, const GWEN_XMLNODE *n2, GWEN_BUFFER *nbuf)
Definition: xml.c:1000
void GWEN_Xml2Db_Context_LeaveDocNode(GWEN_XML2DB_CONTEXT *ctx)
Definition: xml2db.c:85
int GWEN_Xml2Db_Handle_XmlIfNotPathExists(GWEN_XML2DB_CONTEXT *ctx, GWEN_XMLNODE *xmlNode)
Definition: xml2db.c:624
int GWEN_Xml2Db_Handle_DbSetCharValue_internal(GWEN_XML2DB_CONTEXT *ctx, GWEN_XMLNODE *xmlNode, GWEN_DB_NODE *dbCurrent)
Definition: xml2db.c:398
#define DBG_ERROR(dbg_logger, format, args...)
Definition: debug.h:97
GWEN_XMLNODE * GWEN_XMLNode_GetFirstTag(const GWEN_XMLNODE *n)
Definition: xml.c:629
const char * GWEN_XMLNode_GetData(const GWEN_XMLNODE *n)
Definition: xml.c:351
int GWEN_Text_ComparePattern(const char *w, const char *p, int sensecase)
Definition: text.c:1162
int GWEN_DB_SetCharValue(GWEN_DB_NODE *n, uint32_t flags, const char *path, const char *val)
Definition: db.c:922
int GWEN_Xml2Db_Handle_DbSetCharValue(GWEN_XML2DB_CONTEXT *ctx, GWEN_XMLNODE *xmlNode)
Definition: xml2db.c:455
#define GWEN_PATH_FLAGS_PATHMUSTEXIST
Definition: path.h:66
#define DBG_INFO(dbg_logger, format, args...)
Definition: debug.h:164
void GWEN_DB_UnlinkGroup(GWEN_DB_NODE *n)
Definition: db.c:1427
GWEN_XMLNODE * GWEN_XMLNode_List2_GetBack(GWEN_XMLNODE_LIST2 *l)
void GWEN_XMLNode_List2_PushBack(GWEN_XMLNODE_LIST2 *l, GWEN_XMLNODE *p)
const char * GWEN_XMLNode_GetCharValueByPath(GWEN_XMLNODE *n, const char *name, const char *defValue)
Definition: xml.c:892
GWEN_DB_NODE * GWEN_DB_Group_new(const char *name)
Definition: db.c:131
int GWEN_Xml2Db_Handle_XmlEnter(GWEN_XML2DB_CONTEXT *ctx, GWEN_XMLNODE *xmlNode)
Definition: xml2db.c:254
int GWEN_Xml2Db_Handle_DbCreateAndEnterTempGroup(GWEN_XML2DB_CONTEXT *ctx, GWEN_XMLNODE *xmlNode)
Definition: xml2db.c:360
int GWEN_Xml2Db_Handle_DbCreateAndEnterGroup(GWEN_XML2DB_CONTEXT *ctx, GWEN_XMLNODE *xmlNode)
Definition: xml2db.c:327
int GWEN_Xml2Db_Handle_XmlIfCharDataMatches(GWEN_XML2DB_CONTEXT *ctx, GWEN_XMLNODE *xmlNode)
Definition: xml2db.c:467
struct GWEN__XMLNODE GWEN_XMLNODE
Definition: xml.h:148
int GWEN_Xml2Db_HandleChildren(GWEN_XML2DB_CONTEXT *ctx, GWEN_XMLNODE *xmlNode)
Definition: xml2db.c:653
int GWEN_Buffer_AppendString(GWEN_BUFFER *bf, const char *buffer)
Definition: buffer.c:1014
#define GWEN_DB_FLAGS_DEFAULT
Definition: db.h:168
struct GWEN_DATE GWEN_DATE
Definition: gwendate.h:34
int GWEN_Xml2Db_ConvertAndSetCharValue(GWEN_XML2DB_CONTEXT *ctx, GWEN_XMLNODE *xmlNode, GWEN_DB_NODE *dbCurrent, const char *value)
Definition: xml2db.c:144