xmlns.c

00001 /*****************************************************************************
00002  *                               xmlns.c
00003  * This file defines various functions which are used in processing xml 
00004  * namespaces.
00005  *
00006  ****************************************************************************/
00007 
00008 #include <stdio.h>
00009 #include <stdlib.h>
00010 #include "dtd.h"
00011 #include "parser.h"
00012 
00013 #ifdef XMLNS
00014 
00024 static xmlns *
00025 xmlns_push(dtd_parser *p, const ichar *ns, const ochar *url)
00026 { sgml_environment *env = p->environments;
00027   dtd_symbol *n = (*ns ? dtd_add_symbol(p->dtd, ns) : (dtd_symbol *)NULL);
00028   dtd_symbol *u = dtd_add_symbol(p->dtd, url); /* TBD: ochar/ichar */
00029 
00030   /*Invoke the namespace handling function*/
00031   if ( p->on_xmlns )
00032     (*p->on_xmlns)(p, n, u);
00033 
00034   if ( env )
00035     { xmlns *x = sgml_malloc(sizeof(*n));
00036 
00037       x->name = n;
00038       x->url  = u;
00039       x->next = env->xmlns;
00040       env->xmlns = x;
00041 
00042       return x;
00043     }
00044 
00045   return NULL;
00046 }
00047 
00053 void
00054 xmlns_free(sgml_environment *env)
00055 { xmlns *n, *next;
00056 
00057   for(n = env->xmlns; n; n = next)
00058     { next = n->next;
00059 
00060       sgml_free(n);
00061     }
00062 }
00063 
00069 xmlns *
00070 xmlns_find(sgml_environment *env, dtd_symbol *ns)
00071 { for(; env; env = env->parent)
00072     { xmlns *n;
00073 
00074       for(n=env->xmlns; n; n = n->next)
00075         { if ( n->name == ns )
00076             return n;
00077         }
00078     }
00079 
00080   return NULL;
00081 }
00082 
00089 static ichar *
00090 isxmlns(const ichar *s, int nschr)
00091 { if ( s[0]=='x' && s[1]=='m' && s[2]=='l' && s[3] =='n'&& s[4]=='s' )
00092     { if ( !s[5] )
00093         return (ichar *)s+5;                    /* implicit */
00094       if ( s[5] == nschr )
00095         return (ichar *)s+6;
00096     }
00097 
00098   return NULL;
00099 }
00100 
00101 
00105 void
00106 update_xmlns(dtd_parser *p, dtd_element *e, int natts, sgml_attribute *atts)
00107 { dtd_attr_list *al;
00108   int nschr = p->dtd->charfunc->func[CF_NS]; /* : */
00109        
00110   for(al=e->attributes; al; al=al->next)
00111     { dtd_attr *a = al->attribute;
00112       const ichar *name = a->name->name;
00113 
00114       if ( (name = isxmlns(name, nschr)) && /* TBD: flag when processing DTD */
00115            a->type == AT_CDATA &&
00116            (a->def == AT_FIXED || a->def == AT_DEFAULT) )
00117         xmlns_push(p, name, a->att_def.cdata);
00118     }
00119 
00120   for( ; natts-- > 0; atts++ )
00121     { const ichar *name = atts->definition->name->name;
00122 
00123       if ( (name=isxmlns(name, nschr)) && atts->definition->type == AT_CDATA )
00124         xmlns_push(p, name, atts->value.cdata);
00125     }
00126 }
00127 
00128 
00141 int
00142 xmlns_resolve_attribute(dtd_parser *p, dtd_symbol *id,
00143                         const ichar **local, const ichar **url)
00144 { dtd *dtd = p->dtd;
00145   int nschr = dtd->charfunc->func[CF_NS]; /* : */
00146   ichar buf[MAXNMLEN];
00147   ichar *o = buf;
00148   ichar *s;
00149   xmlns *ns;
00150 
00151   for(s=id->name; *s; s++)
00152     { if ( *s == nschr )
00153         { dtd_symbol *n;
00154 
00155           *o = '\0';
00156           *local = s+1;
00157           n = dtd_add_symbol(dtd, buf);
00158 
00159           if ( istrprefix("xml", buf) ) /* XML reserved namespaces */
00160             { *url = n->name;
00161               return TRUE;
00162             } else if ( (ns = xmlns_find(p->environments, n)) )
00163             { if ( ns->url->name[0] )
00164                 *url = ns->url->name;
00165               else
00166                 *url = NULL;
00167               return TRUE;
00168             } else
00169             { *url = n->name;                   /* undefined namespace */
00170               gripe(ERC_EXISTENCE, "namespace", n->name);
00171               return FALSE;
00172             }
00173         }
00174       *o++ = *s;
00175     }
00176 
00177   *local = id->name;
00178 
00179   if ( (p->flags & SGML_PARSER_QUALIFY_ATTS) &&
00180        (ns = p->environments->thisns) && ns->url->name[0] )
00181     *url = ns->url->name;
00182   else
00183     *url = NULL;                        /* no default namespace is defined */
00184 
00185   return TRUE;
00186 }
00187 
00188 
00197 int
00198 xmlns_resolve_element(dtd_parser *p, const ichar **local, const ichar **url)
00199 { sgml_environment *e;
00200 
00201   if ( (e=p->environments) )
00202     { dtd_symbol *id = e->element->name;
00203       dtd *dtd = p->dtd;
00204       int nschr = dtd->charfunc->func[CF_NS]; /* : */
00205       ichar buf[MAXNMLEN];
00206       ichar *o = buf;
00207       ichar *s;
00208       xmlns *ns;
00209   
00210       for(s=id->name; *s; s++)
00211         { if ( *s == nschr )            /* explicit namespace */
00212             { dtd_symbol *n;
00213   
00214               *o = '\0';
00215               *local = s+1;
00216               n = dtd_add_symbol(dtd, buf);
00217 
00218               if ( (ns = xmlns_find(p->environments, n)) )
00219                 { if ( ns->url->name[0] )
00220                     *url = ns->url->name;
00221                   else
00222                     *url = NULL;
00223                   e->thisns = ns;               /* default for attributes */
00224                   return TRUE;
00225                 } else
00226                 { *url = n->name;               /* undefined namespace */
00227                   gripe(ERC_EXISTENCE, "namespace", n->name);
00228                   e->thisns = xmlns_push(p, n->name, n->name); /* define implicitly */
00229                   return FALSE;
00230                 }
00231             }
00232           *o++ = *s;
00233         }
00234   
00235       *local = id->name;
00236   
00237       if ( (ns = xmlns_find(p->environments, NULL)) )
00238         { if ( ns->url->name[0] )
00239             *url = ns->url->name;
00240           else
00241             *url = NULL;
00242           e->thisns = ns;
00243         } else
00244         { *url = NULL;                  /* no default namespace is defined */
00245           e->thisns = NULL;
00246         }
00247 
00248       return TRUE;
00249     } else
00250     return FALSE;
00251 }
00252 
00253 
00254 #endif /*XMLNS*/
00255 

Generated on Wed Jul 26 13:30:46 2006 for XSB by  doxygen 1.4.5