예제 #1
0
/* :nodoc: */
static void relink_namespace(xmlNodePtr reparented)
{
  xmlNodePtr child;

  /* Avoid segv when relinking against unlinked nodes. */
  if(!reparented->parent) return;

  /* Make sure that our reparented node has the correct namespaces */
  if(!reparented->ns && reparented->doc != (xmlDocPtr)reparented->parent)
    xmlSetNs(reparented, reparented->parent->ns);

  /* Search our parents for an existing definition */
  if(reparented->nsDef) {
    xmlNsPtr curr = reparented->nsDef;
    xmlNsPtr prev = NULL;

    while(curr) {
      xmlNsPtr ns = xmlSearchNsByHref(
          reparented->doc,
          reparented->parent,
          curr->href
      );
      /* If we find the namespace is already declared, remove it from this
       * definition list. */
      if(ns && ns != curr) {
        if (prev) {
          prev->next = curr->next;
        } else {
          reparented->nsDef = curr->next;
        }
        nokogiri_root_nsdef(curr, reparented->doc);
      } else {
        prev = curr;
      }
      curr = curr->next;
    }
  }

  /* Only walk all children if there actually is a namespace we need to */
  /* reparent. */
  if(NULL == reparented->ns) return;

  /* When a node gets reparented, walk it's children to make sure that */
  /* their namespaces are reparented as well. */
  child = reparented->children;
  while(NULL != child) {
    relink_namespace(child);
    child = child->next;
  }
}
예제 #2
0
/* :nodoc: */
static void relink_namespace(xmlNodePtr reparented)
{
  xmlChar *name, *prefix;
  xmlNodePtr child;
  xmlNsPtr ns;

  if (reparented->type != XML_ATTRIBUTE_NODE &&
      reparented->type != XML_ELEMENT_NODE) return;

  if (reparented->ns == NULL || reparented->ns->prefix == NULL) {
    name = xmlSplitQName2(reparented->name, &prefix);

    if(reparented->type == XML_ATTRIBUTE_NODE) {
      if (prefix == NULL || strcmp((char*)prefix, XMLNS_PREFIX) == 0) return;
    }

    ns = xmlSearchNs(reparented->doc, reparented, prefix);

    if (ns == NULL && reparented->parent) {
      ns = xmlSearchNs(reparented->doc, reparented->parent, prefix);
    }

    if (ns != NULL) {
      xmlNodeSetName(reparented, name);
      xmlSetNs(reparented, ns);
    }
  }

  /* Avoid segv when relinking against unlinked nodes. */
  if (reparented->type != XML_ELEMENT_NODE || !reparented->parent) return;

  /* Make sure that our reparented node has the correct namespaces */
  if(!reparented->ns && reparented->doc != (xmlDocPtr)reparented->parent)
    xmlSetNs(reparented, reparented->parent->ns);

  /* Search our parents for an existing definition */
  if(reparented->nsDef) {
    xmlNsPtr curr = reparented->nsDef;
    xmlNsPtr prev = NULL;

    while(curr) {
      xmlNsPtr ns = xmlSearchNsByHref(
          reparented->doc,
          reparented->parent,
          curr->href
      );
      /* If we find the namespace is already declared, remove it from this
       * definition list. */
      if(ns && ns != curr) {
        if (prev) {
          prev->next = curr->next;
        } else {
          reparented->nsDef = curr->next;
        }
        nokogiri_root_nsdef(curr, reparented->doc);
      } else {
        prev = curr;
      }
      curr = curr->next;
    }
  }

  /* Only walk all children if there actually is a namespace we need to */
  /* reparent. */
  if(NULL == reparented->ns) return;

  /* When a node gets reparented, walk it's children to make sure that */
  /* their namespaces are reparented as well. */
  child = reparented->children;
  while(NULL != child) {
    relink_namespace(child);
    child = child->next;
  }

  if (reparented->type == XML_ELEMENT_NODE) {
    child = (xmlNodePtr)((xmlElementPtr)reparented)->attributes;
    while(NULL != child) {
      relink_namespace(child);
      child = child->next;
    }
  }
}
예제 #3
0
/* :nodoc: */
static void relink_namespace(xmlNodePtr reparented)
{
  xmlNodePtr child;

  if (reparented->type != XML_ATTRIBUTE_NODE &&
      reparented->type != XML_ELEMENT_NODE) { return; }

  if (reparented->ns == NULL || reparented->ns->prefix == NULL) {
    xmlNsPtr ns = NULL;
    xmlChar *name = NULL, *prefix = NULL;

    name = xmlSplitQName2(reparented->name, &prefix);

    if (reparented->type == XML_ATTRIBUTE_NODE) {
      if (prefix == NULL || strcmp((char*)prefix, XMLNS_PREFIX) == 0) {
        xmlFree(name);
        xmlFree(prefix);
        return;
      }
    }

    ns = xmlSearchNs(reparented->doc, reparented, prefix);

    if (ns == NULL && reparented->parent) {
      ns = xmlSearchNs(reparented->doc, reparented->parent, prefix);
    }

    if (ns != NULL) {
      xmlNodeSetName(reparented, name);
      xmlSetNs(reparented, ns);
    }

    xmlFree(name);
    xmlFree(prefix);
  }

  /* Avoid segv when relinking against unlinked nodes. */
  if (reparented->type != XML_ELEMENT_NODE || !reparented->parent) { return; }

  /* Make sure that our reparented node has the correct namespaces */
  if (!reparented->ns && reparented->doc != (xmlDocPtr)reparented->parent) {
    xmlSetNs(reparented, reparented->parent->ns);
  }

  /* Search our parents for an existing definition */
  if (reparented->nsDef) {
    xmlNsPtr curr = reparented->nsDef;
    xmlNsPtr prev = NULL;

    while (curr) {
      xmlNsPtr ns = xmlSearchNsByHref(
                      reparented->doc,
                      reparented->parent,
                      curr->href
                    );
      /* If we find the namespace is already declared, remove it from this
       * definition list. */
      if (ns && ns != curr && xmlStrEqual(ns->prefix, curr->prefix)) {
        if (prev) {
          prev->next = curr->next;
        } else {
          reparented->nsDef = curr->next;
        }
        nokogiri_root_nsdef(curr, reparented->doc);
      } else {
        prev = curr;
      }
      curr = curr->next;
    }
  }

  /*
   *  Search our parents for an existing definition of current namespace,
   *  because the definition it's pointing to may have just been removed nsDef.
   *
   *  And although that would technically probably be OK, I'd feel better if we
   *  referred to a namespace that's still present in a node's nsDef somewhere
   *  in the doc.
   */
  if (reparented->ns) {
    xmlNsPtr ns = xmlSearchNs(reparented->doc, reparented, reparented->ns->prefix);
    if (ns
        && ns != reparented->ns
        && xmlStrEqual(ns->prefix, reparented->ns->prefix)
        && xmlStrEqual(ns->href, reparented->ns->href)
       ) {
      xmlSetNs(reparented, ns);
    }
  }

  /* Only walk all children if there actually is a namespace we need to */
  /* reparent. */
  if (NULL == reparented->ns) { return; }

  /* When a node gets reparented, walk it's children to make sure that */
  /* their namespaces are reparented as well. */
  child = reparented->children;
  while (NULL != child) {
    relink_namespace(child);
    child = child->next;
  }

  if (reparented->type == XML_ELEMENT_NODE) {
    child = (xmlNodePtr)((xmlElementPtr)reparented)->attributes;
    while(NULL != child) {
      relink_namespace(child);
      child = child->next;
    }
  }
}