As of version 4.3 PHP doesn't support Appending a child from another source document. If you are trying to import information from multiple sources into a final document [for transformation using XSL as an example] then you can have problems. This technique can be used to do it though.
I am assuming you have two documents open, $xmldoc1 and $xmldoc2 and you have selected [via XPath or explicit searching] the nodes you want in each document. Thus $xmldoc1_appending_node is the node you would like to add $xmldoc2_importnode to.
<?
// first we create a temporary node within the document we want to add to.
$temp_importnode = $xmldoc1->create_element("import");
// now we have a node that is in the right document context we can clone the one we want into this one.
$temp_importnode = $xmldoc_importnode->clone_node(true);
// by using true in the above call to clone_node() we copy all of the child nodes as well. Use false or nothing if you just want the containing node with no children.
$xmldoc1_appending->append_child($importnode);
?>
Now your document contains the new nodes imported from a different document.
DomNode->append_child
(No version information available, might be only in CVS)
DomNode->append_child — Agrega un nuevo hijo al final del grupo de hijos
Descripción
Esta función agrega un hijo a una lista existente de hijos o crea una nueva lista de hijos.
Lista de parámetros
- nodo_nuevo
-
El nodo que está siendo agregado. Puede ser creado p.ej. con DomDocument->create_element, DomDocument->create_text_node etc. o simplemente usando cualquier otro nodo.
Note: No es posible agregar un DOMAttribute usando este método. Use DomElement->set_attribute() en su lugar.
Valores retornados
Devuelve el nodo agregado en caso de éxito, o FALSE si ocurre un error.
Registro de cambios
| Versión | Descripción |
|---|---|
| 4.3.0 | Ya no es posible insertar un nodo desde otro documento. |
| 4.3.0 | Antes de PHP 4.3.0, el nuevo hijo es duplicado antes de agregarse. Por lo tanto el nuevo hijo es una nueva copia que puede ser modificada sin cambiar el nodo que fue pasado a esta función. Si el nodo pasado tiene hijos, ellos serán duplicados también, lo que facilita la duplicación de grandes segmentos de un documento XML. El valor de retorno es el hijo agregado. Si planea realizar modificaciones posteriores sobre el hijo agregado, debe usar el nodo devuelto. |
| 4.3.0 y 4.3.1 | El nuevo hijo nodo_nuevo es separado primero de su contexto actual, si ya se trata de un hijo de DomNode. Por lo tanto el nodo_nuevo es movido y no copiado. Este es el comportamiento de acuerdo a las especificaciones del W3C. Si necesita el comportamiento antiguo, use DomNode->clone_node antes de agregar. |
| 4.3.2 | El nuevo hijo nodo_nuevo es primero separado de su contexto actual, si éste ya existe en el árbol. Se aplican las mismas reglas. |
Ejemplos
El siguiente ejemplo agrega un nuevo nodo tipo elemento a un documento nuevo y define el atributo align como left.
Example #1 Agregar un hijo
<?php
$doc = domxml_new_doc("1.0");
$nodo = $doc->create_element("para");
$nodo_nuevo = $doc->append_child($nodo);
$nodo_nuevo->set_attribute("align", "left");
?>
El anterior ejemplo pudo ser escrito también como:
Example #2 Agregar un hijo
<?php
$doc = domxml_new_doc("1.0");
$nodo = $doc->create_element("para");
$nodo->set_attribute("align", "left");
$nodo_nuevo = $doc->append_child($nodo);
?>
Un ejemplo más complejo se presenta a continuación. Primero busca cierto elemento, lo duplica incluyendo sus hijos y lo agrega como un hermano. Finalmente un nuevo atributo es agregado a uno de los hijos del nuevo hermano y el documento completo es volcado.
Example #3 Agregar un hijo
<?php
include("ejemplo.inc");
if (!$dom = domxml_open_mem($cadena_xml)) {
echo "Ocurrió un error al analizar el documento\n";
exit;
}
$elementos = $dom->get_elements_by_tagname("informaltable");
print_r($elementos);
$elemento = $elementos[0];
$padre = $elemento->parent_node();
$nodo_nuevo = $padre->append_child($elemento);
$hijos = $nodo_nuevo->children();
$atr = $hijos[1]->set_attribute("align", "left");
$archivo_xml = $dom->dump_mem();
echo htmlentities($archivo_xml);
?>
El ejemplo anterior pudo escribirse también con DomNode->insert_before en lugar de DomNode->append_child.
Migración a PHP 5
Debe usar Material que falta.
DomNode->append_child
12-Feb-2006 04:03
01-Nov-2002 09:46
Be careful of the order you append childs. (PHP <= 4.2)
If you create let's say:
$x_html = $x_doc->create_element('html');
$x_head, $x_title, $x_meta, $x_link and $x_body in the same way.
If you:
$x_head->append_child($x_title);
$x_head->append_child($x_meta);
$x_head->append_child($x_link);
$x_html->append_child($x_head);
$x_body_backup = $x_html->append_child($x_body);
/* here */
$x_doc->append_child($x_html);
If you now try to modify $x_body_backup.. it will no longer be able to modify the actualy XML tree, because you appended the HTML tree to the DomDocument.. and it has copied ALL the nodes at the end of the DomDocument, so the reference you now have in $x_body_backup is not valid anymore! If you had modified it where the /* here */ line is.. the $x_body_backup would still be valid.. but not after the $x_doc->append_child($x_html);
What you can do is, reverse the order of your appendings.. so that you append the highest level node at the end.. so that your reference is still valid after, or wait till you have filled all of the nodes you wanted to add before you append it to your parent node.
