Variant c_SimpleXMLElement::t___set(Variant name, Variant value) {
  if (m_node == nullptr) return uninit_null();

  String svalue = value.toString();
  xmlChar *sv = svalue.empty() ? nullptr : (xmlChar *)svalue.data();
  String sname = name.toString();

  Variant node;
  if (m_is_attribute) {
    node = m_attributes[name];
  } else {
    node = m_children[name];
  }

  xmlNodePtr newnode = nullptr;
  if (node.isObject()) {
    c_SimpleXMLElement *elem =
      node.toObject().getTyped<c_SimpleXMLElement>();
    if (elem->m_node) {
      xmlNodePtr tempnode;
      while ((tempnode = (xmlNodePtr)elem->m_node->children)) {
        xmlUnlinkNode(tempnode);
      }
      elem->m_children = Array::Create();
      change_node_zval(elem->m_node, svalue);
      newnode = elem->m_node;
    }
  } else if (node.isArray()) {
    raise_warning("Cannot assign to an array of nodes "
                  "(duplicate subnodes or attr detected)");
  } else if (m_is_attribute) {
    if (name.isInteger()) {
      raise_warning("Cannot change attribute number %" PRId64
                    " when only %zd attributes exist", name.toInt64(),
                    m_attributes.toArray().size());
    } else {
      newnode = (xmlNodePtr)xmlNewProp(m_node, (xmlChar *)sname.data(), sv);
    }
  } else {
    if (sname.empty() || name.isInteger()) {
      newnode = xmlNewTextChild(m_node->parent, m_node->ns,
                                m_node->name, sv);
    } else {
      newnode = xmlNewTextChild(m_node, m_node->ns,
                                (xmlChar *)sname.data(), sv);
    }
  }

  if (newnode) {
    String ns((char*)m_node->ns, CopyString);
    Object child = create_element(m_root, m_doc, newnode, ns, false);
    if (m_is_attribute) {
      m_attributes.set(name, child);
      m_children.set(s_attributes, m_attributes);
    } else {
      m_children.set(name, child);
    }
  }

  return uninit_null();
}
Variant c_SimpleXMLElement::t___set(Variant name, Variant value) {
  if (m_node == nullptr) return uninit_null();

  String svalue = value.toString();
  xmlChar *sv = svalue.empty() ? nullptr : (xmlChar *)svalue.data();
  String sname = name.toString();

  Variant node;
  if (m_is_attribute) {
    node = m_attributes[name];
  } else {
    node = m_children[name];
  }

  xmlNodePtr newnode = nullptr;
  if (node.isObject()) {
    c_SimpleXMLElement *elem =
      node.toObject().getTyped<c_SimpleXMLElement>();
    if (elem->m_node) {
      xmlNodePtr tempnode;
      while ((tempnode = (xmlNodePtr)elem->m_node->children)) {
        xmlUnlinkNode(tempnode);
      }
      elem->m_children = Array::Create();
      change_node_zval(elem->m_node, svalue);
      newnode = elem->m_node;
    }
  } else if (node.isArray()) {
    raise_warning("Cannot assign to an array of nodes "
                  "(duplicate subnodes or attr detected)");
  } else if (m_is_attribute) {
    if (name.isInteger()) {
      raise_warning("Cannot change attribute number %" PRId64
                    " when only %zd attributes exist", name.toInt64(),
                    m_attributes.toArray().size());
    } else {
      newnode = (xmlNodePtr)xmlNewProp(m_node, (xmlChar *)sname.data(), sv);
    }
  } else {
    if (sname.empty() || name.isInteger()) {
      newnode = xmlNewTextChild(m_node->parent, m_node->ns,
                                m_node->name, sv);
    } else {
      newnode = xmlNewTextChild(m_node, m_node->ns,
                                (xmlChar *)sname.data(), sv);
    }
  }

  if (newnode) {
    String ns((char*)m_node->ns, CopyString);
    Object child = create_element(m_root, m_doc, newnode, ns, false);
    if (m_is_attribute) {
      m_attributes.set(name, child);
      m_children.set(s_attributes, m_attributes);
    } else {
      m_children.set(name, child);
    }
  }

  return uninit_null();
}