static const char *
soap_push_ns_prefix(struct soap *soap, const char *id, const char *ns, int flag)
{ register struct soap_nlist *np;
  if (!id)
  { struct Namespace *n;
    for (n = soap->local_namespaces; n && n->id; n++)
    { if (n->ns == ns || !strcmp(n->ns, ns))
      { id = n->id;
        break;
      }
    }
    if (!id)
    { sprintf(soap->tag, SOAP_DOMID_FORMAT, soap->idnum++);
      id = soap->tag;
    }
  }
  /* fix advance generation of xmlns, when element (level) is not output yet */
  if (flag)
    soap->level++;
  np = soap_push_namespace(soap, id, ns);
  if (flag)
    soap->level--;
  if (!np)
    return NULL;
  if (!np->ns)
  { np->ns = soap->local_namespaces[np->index].out;
    if (!np->ns)
      np->ns = soap->local_namespaces[np->index].ns;
  }
  np->index = 0; /* for C14N utilized mark */
  if (*np->id)
  { sprintf(soap->msgbuf, "xmlns:%s", np->id);
    out_attribute(soap, NULL, soap->msgbuf, ns, NULL, flag);
  }
  else
    out_attribute(soap, NULL, "xmlns", ns, NULL, flag);
  return np->id;
}
SOAP_FMAC1
int
SOAP_FMAC2
soap_out_xsd__anyType(struct soap *soap, const char *tag, int id, const struct soap_dom_element *node, const char *type)
{ if (node)
  { const char *prefix; /* namespace prefix, if namespace is present */
    size_t colon;
    if (!(soap->mode & SOAP_DOM_ASIS))
    { const struct soap_dom_attribute *att;
      for (att = node->atts; att; att = att->next)
      { if (att->name && att->data && !strncmp(att->name, "xmlns:", 6))
	{ if (soap_push_namespace(soap, att->name + 6, att->data) == NULL)
            return soap->error;
	}
        else if (att->name && att->data && !strcmp(att->name, "xmlns"))
	{ if (soap_push_namespace(soap, "", att->data) == NULL)
            return soap->error;
	}
      }
    }
    if (node->name)
      tag = node->name;
    else if (!tag)
      tag = "-";
    DBGLOG(TEST, SOAP_MESSAGE(fdebug, "DOM node '%s' output at level %u\n", tag, soap->level));
    if ((prefix = strchr(tag, ':')))
    { colon = prefix - tag + 1;
      if (colon > sizeof(soap->tag))
        colon = sizeof(soap->tag);
    }
    else
      colon = 0;
    prefix = NULL;
    if (node->nstr && *node->nstr && !(soap->mode & SOAP_DOM_ASIS))
    { if (colon)
      { strncpy(soap->tag, tag, colon - 1);
        soap->tag[colon - 1] = '\0';
        if ((prefix = soap_push_ns_prefix(soap, soap->tag, node->nstr, 1)) == NULL
         || out_element(soap, node, prefix, tag + colon))
          return soap->error;
      }
      else
      { if ((prefix = soap_lookup_ns_prefix(soap, node->nstr)))
        { if (out_element(soap, node, prefix, tag + colon))
            return soap->error;
        }
        else
	{ if ((prefix = soap_push_ns_prefix(soap, NULL, node->nstr, 1)) == NULL
           || out_element(soap, node, prefix, tag + colon))
            return soap->error;
        }
      }
    }
    else
    { colon = 0;
      if (out_element(soap, node, NULL, tag))
        return soap->error;
    }
    if (!node->type || !node->node)
    { struct soap_dom_attribute *att;
      struct soap_dom_element *elt;
      for (att = node->atts; att; att = att->next)
      { if (att->name)
        { if (att->nstr && !(soap->mode & SOAP_DOM_ASIS))
          { const char *p;
            if ((att->nstr == node->nstr || (node->nstr && !strcmp(att->nstr, node->nstr))) && prefix)
	    { if (out_attribute(soap, prefix, att->name, att->data, att->wide, 0))
	        return soap->error;
	    }
	    else if ((p = soap_lookup_ns_prefix(soap, att->nstr)))
	    { if (out_attribute(soap, p, att->name, att->data, att->wide, 0))
	        return soap->error;
	    }
	    else if (!strncmp(att->name, "xml", 3))
	    { if (out_attribute(soap, NULL, att->name, att->data, att->wide, 0))
                return soap->error;
	    }
	    else if ((p = soap_push_ns_prefix(soap, NULL, att->nstr, 0)) == NULL
	          || out_attribute(soap, p, att->name, att->data, att->wide, 0))
              return soap->error;
          }
	  else if (soap_attribute(soap, att->name, att->wide ? soap_wchar2s(soap, att->wide) : att->data))
            return soap->error;
        }
      }
      if ((soap->mode & SOAP_DOM_ASIS) && !node->data && !node->wide && !node->elts && !node->tail)
      { if (*tag != '-' && soap_element_start_end_out(soap, tag))
          return soap->error;
      }
      else
      { if (*tag != '-' && soap_element_start_end_out(soap, NULL))
          return soap->error;
        if (node->data)
        { if (soap_string_out(soap, node->data, 0))
            return soap->error;
        }
        else if (node->wide)
        { if (soap_wstring_out(soap, node->wide, 0))
            return soap->error;
        }
        for (elt = node->elts; elt; elt = elt->next)
        { if (soap_out_xsd__anyType(soap, tag, 0, elt, NULL))
            return soap->error;
        }
        if (node->tail && soap_send(soap, node->tail))
          return soap->error;
        if (!prefix || !*prefix)
        { DBGLOG(TEST, SOAP_MESSAGE(fdebug, "End of DOM node '%s'\n", tag + colon));
          if (soap_element_end_out(soap, tag + colon))
            return soap->error;
        }
        else
        { char *s;
          if (strlen(prefix) + strlen(tag + colon) < sizeof(soap->msgbuf))
	    s = soap->msgbuf;
	  else
	  { s = (char*)SOAP_MALLOC(soap, strlen(prefix) + strlen(tag + colon) + 2);
            if (!s)
              return soap->error = SOAP_EOM;
	  }
          DBGLOG(TEST, SOAP_MESSAGE(fdebug, "End of DOM node '%s'\n", tag));
	  sprintf(s, "%s:%s", prefix, tag + colon);
	  soap_pop_namespace(soap);
          if (soap_element_end_out(soap, s))
            return soap->error;
          if (s != soap->msgbuf)
	    SOAP_FREE(soap, s);
        }
      }
    }
  }
  return SOAP_OK;
}
示例#3
0
SOAP_FMAC1
int
SOAP_FMAC2
soap_out_xsd__anyType(struct soap *soap, const char *tag, int id, const struct soap_dom_element *node, const char *type)
{ if (node)
  { struct soap_dom_element *elt;
    struct soap_dom_attribute *att;
    register struct soap_ilist *p = NULL, *q;
    struct Namespace *ns = NULL;
    const char *prefix;		/* namespace prefix, if namespace is present */
    size_t colon = 0;
    if (node->name)
      tag = node->name;
    if (!tag)
      tag = "_";
    if ((prefix = strchr(tag, ':')))
    { colon = prefix - tag + 1;
      if (colon > sizeof(soap->tag))
        colon = sizeof(soap->tag);
    }
    prefix = NULL;
    DBGLOG(TEST, SOAP_MESSAGE(fdebug, "DOM node '%s'\n", tag));
    if (node->nstr)
    { if ((p = soap_lookup_ns(soap, node->nstr)))
      { prefix = p->id;
        p = NULL;
        if (out_element(soap, node, prefix, tag + colon, NULL))
          return soap->error;
      }
      else if (colon)
      { strncpy(soap->tag, tag, colon - 1);
        soap->tag[colon - 1] = '\0';
        if (!(p = soap_enter_ns(soap, soap->tag, node->nstr)))
          return soap->error = SOAP_EOM;
        prefix = p->id;
        if (out_element(soap, node, prefix, tag + colon, node->nstr))
          return soap->error;
      }
      else
      { for (ns = soap->local_namespaces; ns && ns->id; ns++)
          if (ns->ns == node->nstr || !strcmp(ns->ns, node->nstr))
          { /* if (soap->encodingStyle || ns == soap->local_namespaces) */
              prefix = ns->id;
            if (out_element(soap, node, ns->id, tag + colon, NULL))
              return soap->error;
            break;
          }
        if (!ns || !ns->id)
        { sprintf(soap->tag, SOAP_DOMID_FORMAT, soap->idnum++);
          if (!(p = soap_enter_ns(soap, soap->tag, node->nstr)))
            return soap->error = SOAP_EOM;
          prefix = p->id;
          if (out_element(soap, node, prefix, tag + colon, node->nstr))
            return soap->error;
        }
      }
    }
    else if (out_element(soap, node, NULL, tag + colon, NULL))
      return soap->error;
    if (node->type && node->node)
      return SOAP_OK;
    for (att = node->atts; att; att = att->next)
    { if (att->name)
      { if (att->nstr)
        { if ((att->nstr == node->nstr || (node->nstr && !strcmp(att->nstr, node->nstr))) && prefix)
	  { if (out_attribute(soap, prefix, att->name, att->data))
	      return soap->error;
	  }
	  else if ((q = soap_lookup_ns(soap, att->nstr)))
	  { if (out_attribute(soap, q->id, att->name, att->data))
	      return soap->error;
	  }
	  else
	  { for (ns = soap->local_namespaces; ns && ns->id; ns++)
            { if (ns->ns == att->nstr || !strcmp(ns->ns, att->nstr))
	      { if (out_attribute(soap, ns->id, att->name, att->data))
	          return soap->error;
	        break;
	      }
	    }
	    if (!ns || !ns->id)
            { sprintf(soap->msgbuf, "xmlns:"SOAP_DOMID_FORMAT, soap->idnum++);
	      if (soap_attribute(soap, soap->msgbuf, att->nstr))
	        return soap->error;
	      strcat(soap->msgbuf, ":");
	      strcat(soap->msgbuf, att->name);
	      if (soap_attribute(soap, soap->msgbuf + 6, att->data))
	        return soap->error;
            }
          }
        }
	else if (soap_attribute(soap, att->name, att->data))
          return soap->error;
      }
    }
    if (soap_element_start_end_out(soap, NULL))
      return soap->error;
    if (node->data || node->wide || node->elts)
    { if (node->data)
      { if (soap_string_out(soap, node->data, 0))
          return soap->error;
      }
      else if (node->wide)
      { if (soap_wstring_out(soap, node->wide, 0))
          return soap->error;
      }
      else
      { for (elt = node->elts; elt; elt = elt->next)
          if (soap_out_xsd__anyType(soap, tag, 0, elt, NULL))
            return soap->error;
      }
    }
    DBGLOG(TEST, SOAP_MESSAGE(fdebug, "End of DOM node '%s'\n", tag + colon));
    if (soap_send_raw(soap, "</", 2))
      return soap->error;
    if (prefix)
      if (soap_send(soap, prefix) || soap_send_raw(soap, ":", 1))
        return soap->error;
    if (soap_send(soap, tag + colon) || soap_send_raw(soap, ">", 1))
      return soap->error;
    if (p)
      p->level = 0; /* xmlns binding is out of scope */
  }
  return SOAP_OK;
}