xmlglobalize.c

Go to the documentation of this file.
00001 /***************************************************************************
00002  begin       : Wed Feb 27 2008
00003  copyright   : (C) 2008 by Martin Preuss
00004  email       : martin@libchipcard.de
00005 
00006  ***************************************************************************
00007  *                                                                         *
00008  *   This library is free software; you can redistribute it and/or         *
00009  *   modify it under the terms of the GNU Lesser General Public            *
00010  *   License as published by the Free Software Foundation; either          *
00011  *   version 2.1 of the License, or (at your option) any later version.    *
00012  *                                                                         *
00013  *   This library is distributed in the hope that it will be useful,       *
00014  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00015  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     *
00016  *   Lesser General Public License for more details.                       *
00017  *                                                                         *
00018  *   You should have received a copy of the GNU Lesser General Public      *
00019  *   License along with this library; if not, write to the Free Software   *
00020  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston,                 *
00021  *   MA  02111-1307  USA                                                   *
00022  *                                                                         *
00023  ***************************************************************************/
00024 
00025 
00026 
00027 
00028 GWEN_XMLNODE_NAMESPACE *GWEN_XMLGL__FindNameSpaceByUrl(GWEN_XMLNODE_NAMESPACE_LIST *l,
00029                                                        const char *s) {
00030   GWEN_XMLNODE_NAMESPACE *ns;
00031 
00032   assert(l);
00033   ns=GWEN_XMLNode_NameSpace_List_First(l);
00034   while(ns) {
00035     const char *d;
00036 
00037     d=GWEN_XMLNode_NameSpace_GetUrl(ns);
00038     if (d && strcasecmp(d, s)==0)
00039       return ns;
00040     ns=GWEN_XMLNode_NameSpace_List_Next(ns);
00041   }
00042 
00043   return NULL;
00044 }
00045 
00046 
00047 
00048 GWEN_XMLNODE_NAMESPACE *GWEN_XMLGL__GetNameSpaceByPrefix(GWEN_XMLNODE *n,
00049                                                          const char *prefix) {
00050   while(n) {
00051     if (n->type==GWEN_XMLNodeTypeTag) {
00052       GWEN_XMLNODE_NAMESPACE *ns;
00053 
00054       DBG_ERROR(0, "Checking in node [%s]", GWEN_XMLNode_GetData(n));
00055       ns=GWEN_XMLNode_NameSpace_List_First(n->nameSpaces);
00056       while(ns) {
00057         const char *d;
00058 
00059         d=GWEN_XMLNode_NameSpace_GetName(ns);
00060         if (d && strcasecmp(d, prefix)==0)
00061           return ns;
00062         ns=GWEN_XMLNode_NameSpace_List_Next(ns);
00063       }
00064     }
00065 
00066     n=n->parent;
00067   }
00068 
00069   return NULL;
00070 }
00071 
00072 
00073 
00074 int GWEN_XMLGL__TranslateName(GWEN_XMLNODE *n,
00075                               GWEN_XMLNODE_NAMESPACE_LIST *l,
00076                               char **pValue) {
00077   GWEN_XMLNODE_NAMESPACE *ns;
00078   char *dcopy=NULL;
00079   char *v;
00080   const char *prefix;
00081   const char *name;
00082   
00083   /* split into prefix and value */
00084   dcopy=strdup(*pValue);
00085   v=strchr(dcopy, ':');
00086   if (v) {
00087     *v=0;
00088     prefix=dcopy;
00089     name=v+1;
00090   }
00091   else {
00092     prefix="";
00093     name=dcopy;
00094   }
00095 
00096   /* find definition for namespace in this and parent nodes */
00097   ns=GWEN_XMLGL__GetNameSpaceByPrefix(n, prefix);
00098   if (ns) {
00099     GWEN_XMLNODE_NAMESPACE *newNs;
00100 
00101     /* find new namespace in list of redefined namespaces */
00102     newNs=GWEN_XMLGL__FindNameSpaceByUrl(l, GWEN_XMLNode_NameSpace_GetUrl(ns));
00103     if (newNs) {
00104       char *newValue;
00105 
00106       /* translate prefix part of the name */
00107       newValue=(char*)malloc(strlen(GWEN_XMLNode_NameSpace_GetName(newNs))+
00108                              strlen(name)+1+1);
00109       assert(newValue);
00110       strcpy(newValue, GWEN_XMLNode_NameSpace_GetName(newNs));
00111       strcat(newValue, ":");
00112       strcat(newValue, name);
00113       free(*pValue);
00114       *pValue=newValue;
00115     }
00116     else {
00117       DBG_ERROR(GWEN_LOGDOMAIN,
00118                 "Namespace for [%s] not in list, should not happen.",
00119                 GWEN_XMLNode_NameSpace_GetUrl(ns));
00120       abort();
00121     }
00122     free(dcopy);
00123   }
00124   else {
00125     DBG_ERROR(GWEN_LOGDOMAIN, "No definition for namespace \"%s\" found", prefix);
00126     free(dcopy);
00127     return GWEN_ERROR_NO_DATA;
00128   }
00129 
00130   return 0;
00131 }
00132 
00133 
00134 
00135 int GWEN_XMLGL__SampleNameSpaces(GWEN_XMLNODE *n,
00136                                  GWEN_XMLNODE_NAMESPACE_LIST *l,
00137                                  uint32_t *pLastId) {
00138   GWEN_XMLNODE *nn;
00139 
00140   if (n->type==GWEN_XMLNodeTypeTag) {
00141     GWEN_XMLNODE_NAMESPACE *ns;
00142     GWEN_XMLPROPERTY *pr;
00143     int rv;
00144   
00145     ns=GWEN_XMLNode_NameSpace_List_First(n->nameSpaces);
00146     while(ns) {
00147       const char *url;
00148   
00149       url=GWEN_XMLNode_NameSpace_GetUrl(ns);
00150       if (url) {
00151         if (GWEN_XMLGL__FindNameSpaceByUrl(l, url)==NULL) {
00152           char namebuf[32];
00153           GWEN_XMLNODE_NAMESPACE *newNs;
00154   
00155           snprintf(namebuf, sizeof(namebuf)-1, "_%d_", ++(*pLastId));
00156           newNs=GWEN_XMLNode_NameSpace_new(namebuf, url);
00157           GWEN_XMLNode_NameSpace_List_Add(newNs, l);
00158         }
00159       }
00160       ns=GWEN_XMLNode_NameSpace_List_Next(ns);
00161     }
00162   
00163     /* translate some properties */
00164     pr=n->properties;
00165     while(pr) {
00166       if (pr->name && pr->value) {
00167         if (strcasecmp(pr->name, "type")==0 ||
00168             strcasecmp(pr->name, "ref")==0 ||
00169             strcasecmp(pr->name, "base")==0) {
00170           rv=GWEN_XMLGL__TranslateName(n, l, &(pr->value));
00171           if (rv) {
00172             DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00173             return rv;
00174           }
00175         }
00176       }
00177       pr=pr->next;
00178     }
00179   
00180     /* translate this node */
00181     if (n->data) {
00182       rv=GWEN_XMLGL__TranslateName(n, l, &(n->data));
00183       if (rv) {
00184         DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00185         return rv;
00186       }
00187     }
00188   }
00189 
00190   /* sample and rename children */
00191   nn=GWEN_XMLNode_List_First(n->children);
00192   while(nn) {
00193     int rv;
00194 
00195     rv=GWEN_XMLGL__SampleNameSpaces(nn, l, pLastId);
00196     if (rv)
00197       return rv;
00198     nn=GWEN_XMLNode_List_Next(nn);
00199   }
00200 
00201   return 0;
00202 }
00203 
00204 
00205 
00206 void GWEN_XMLGL__ClearNameSpaces(GWEN_XMLNODE *n) {
00207   GWEN_XMLNODE *nn;
00208 
00209   GWEN_XMLNode_NameSpace_List_Clear(n->nameSpaces);
00210 
00211   nn=GWEN_XMLNode_List_First(n->children);
00212   while(nn) {
00213     GWEN_XMLGL__ClearNameSpaces(nn);
00214     nn=GWEN_XMLNode_List_Next(nn);
00215   }
00216 }
00217 
00218 
00219 
00220 int GWEN_XMLNode_GlobalizeWithList(GWEN_XMLNODE *n,
00221                                    GWEN_XMLNODE_NAMESPACE_LIST *l,
00222                                    uint32_t *pLastId) {
00223   int rv;
00224 
00225   rv=GWEN_XMLGL__SampleNameSpaces(n, l, pLastId);
00226   if (rv<0) {
00227     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00228     return rv;
00229   }
00230   GWEN_XMLGL__ClearNameSpaces(n);
00231 
00232   return 0;
00233 }
00234 
00235 
00236 
00237 int GWEN_XMLNode_Globalize(GWEN_XMLNODE *n) {
00238   GWEN_XMLNODE_NAMESPACE_LIST *l;
00239   uint32_t lastId=0;
00240   int rv;
00241 
00242   l=GWEN_XMLNode_NameSpace_List_new();
00243   rv=GWEN_XMLNode_GlobalizeWithList(n, l, &lastId);
00244   if (rv<0) {
00245     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00246     GWEN_XMLNode_NameSpace_List_free(l);
00247     return rv;
00248   }
00249   GWEN_XMLNode_NameSpace_List_free(n->nameSpaces);
00250   n->nameSpaces=l;
00251 
00252   return 0;
00253 }
00254 
00255 
00256 
00257 
00258 
00259 
00260 
00261 
00262 
00263 
00264 
00265 
Generated on Mon Jul 5 22:51:15 2010 for gwenhywfar by  doxygen 1.6.3