ajouter du xml avec appendChild

Eléphant du PHP | 209 Messages

27 août 2008, 15:52

Salut,

j'utilise la classe DomDocument pour créer un fichier xml :
			$this->domtofNewFig = $this->domtof->createElement('figure');
			$figure = $this->domtof->createTextNode($this->figRef[$k].$captions[$k]);
			$this->domtofNewFig->setAttribute('ref', $ref);
			$this->domtofNewFig->appendChild($figure);
			$tof = $this->domtof->getElementsByTagName('tableoffigures')->item(0);
			$tof->appendChild($this->domtofNewFig);
Le problème, c'est que $this->figRef[$k] et $captions[$k] contiennent déjà du xml et donc des balises mais celles-cies sont remplacées par < et > ce qui me pose problème.
N'étant pas très familier avec cette classe je ne sais pas s'il y a une méthode qui résoud ce problème ou non.
Merci d'avance pour vos éclaircicements.

Modérateur PHPfrance
Modérateur PHPfrance | 2575 Messages

27 août 2008, 20:25

C'est normal car tu ajoute du code xml dans un TextNode comme un contenu de balise, c'est à dire comme une donnée. C'est pour cela que les < > sont transformés en code texte.

Voici l'instruction qui en témoigne :
$figure = $this->domtof->createTextNode($this->figRef[$k].$captions[$k]); 
Ceci dit, je ne sait pas ce que tu veux vraiment faire.
--------//////----//---//----//////
-------//---//----//---//----//---//
------//////----//////-----//////
-----||--------||--||---||
Prendre le recul n'est pas une perte de temps.


ps: Affrontez moi dans l'arène

Eléphant du PHP | 209 Messages

27 août 2008, 22:28

C'est normal car tu ajoute du code xml dans un TextNode comme un contenu de balise, c'est à dire comme une donnée. C'est pour cela que les < > sont transformés en code texte.

Voici l'instruction qui en témoigne :
$figure = $this->domtof->createTextNode($this->figRef[$k].$captions[$k]); 
Ceci dit, je ne sait pas ce que tu veux vraiment faire.

Oui, je sais, mais n'y aurait-il pas moyen de ne pas transformer ces balises car justement $this->figRef[$k].$captions[$k] contient déjà du code xml donc des balises...

Modérateur PHPfrance
Modérateur PHPfrance | 2575 Messages

27 août 2008, 22:42

Il faut transformer leur contenu xml en objets dom puis les greffer à leur nœud d'attachement.
--------//////----//---//----//////
-------//---//----//---//----//---//
------//////----//////-----//////
-----||--------||--||---||
Prendre le recul n'est pas une perte de temps.


ps: Affrontez moi dans l'arène

Eléphant du PHP | 209 Messages

27 août 2008, 22:46

Comme je suis très novice pour le moment avec Dom, j'aimerais bien un petit exemple.

Voici par exemple le type de xml que j'aimerai ajouter :

Du texte bla bla bla <balise attr="truc" attr2="much">texte</balise> texte bla bla bla bidule bla <balise attr="trucbidule" attr2="muchtruc">texte ppoupipou </balise> texte bla bla

en gros ça a cette forme.

Ou peut être qu'il y a une méthode qui fait ça toute seule ?

Modérateur PHPfrance
Modérateur PHPfrance | 2575 Messages

28 août 2008, 09:27

J'aimerai comprendre le pourquoi du comment pour pouvoir t'aider. Que veux-tu faire ? explique avec un exemple ce que tu veux avoir comme résultat et avec quelles données de base, je suis tout ouille.

Par ailleurs, le type xml que tu as donné comme exemple :
Du texte bla bla bla <balise attr="truc" attr2="much">texte</balise> texte bla bla bla bidule bla <balise attr="trucbidule" attr2="muchtruc">texte ppoupipou </balise> texte bla bla
contient des erreurs, car on ne peut pas avoir du texte à l'extérieur des balises dans un document XML. Ce n'est pas comme HTML.

XML est un arbre hiérarchisé de nœuds (balises) où un nœud peut contenir soit d'autres sous-nœuds ou bien du texte. Un nœud qui contient du texte (une valeur) est dit nœud terminal (Element qui a un TextNode) et ne peut contenir un autre sous-arbre. Contrairement à un nœud dit branche (Element qui n'a pas de TextNode) qui lui peut contenir d'autres sous-noeuds mais pas de texte (valeur).

En Dom/XML, une balise est nommée Element à la quelle on peut affecter des attributs (Attributes) et/ou un TextNode. Quand un Element doit contenir un ensemble de sous-nœuds (d'autres balises) il suffit de les lui affecter. La méthode AppendChild permet de faire des affectations d'objets TextNode ou Element à un Element de travail.
--------//////----//---//----//////
-------//---//----//---//----//---//
------//////----//////-----//////
-----||--------||--||---||
Prendre le recul n'est pas une perte de temps.


ps: Affrontez moi dans l'arène

Eléphant du PHP | 209 Messages

29 août 2008, 09:36

D'accord, merci de t'attarder sur mon problème.
J'explique donc plus en détails.
En fait il s'agit d'un document (article ou livre) et j'aimerai faire un système permettant de l'exporter en xml. Comme il s'agit d'articles scientifiques, il y a, dans le texte, des balises "math" qui se baladent. Donc le document a la forme suivante :

Code : Tout sélectionner

<?xml version="1.0" encoding="utf-8" ?> <document> <chapitre nb="1" titre="titre du chapitre> <section nb="1" titre="titre de la section" /> du texte <math type="math" nb="1">2+2=4</math> du texte encore du texte... </chapitre> </document>
Et donc en gros, il faudrait déjà que je mette des balises <texte></texte> autour du texte alors ?
Comme ça :

Code : Tout sélectionner

<?xml version="1.0" encoding="utf-8" ?> <document> <chapitre nb="1" titre="titre du chapitre> <section nb="1" titre="titre de la section" /> <texte>du texte </texte><math type="math" nb="1">2+2=4</math></texte> du texte encore du texte...</texte> </chapitre> </document>
Donc en clair, ce que je voudrais faire, c'est inclure cette partie :

Code : Tout sélectionner

<texte>du texte </texte><math type="math" nb="1">2+2=4</math></texte> du texte encore du texte...</texte>
dans la partie section, via une méthode similaire à appendChild sauf que son argument contient déjà du xml donc qu'il ne faut pas remplacer les balises.

Modérateur PHPfrance
Modérateur PHPfrance | 2575 Messages

29 août 2008, 12:25

Bon, voici un exemple de comment insérer un document xml dans un autre à un emplacement bien défini.
<?php
/*********************************************/
/* INSERTION D'UN DOCUMENT XML DANS UN AUTRE */
/* *******************************************/

//Document de base
$xml1 = '<document>
  <chapitre nb="1" titre="titre du chapitre 1">
  	<section nb="1" titre="titre de la section 1" />
  	<section nb="2" titre="titre de la section 2" />
  </chapitre>
  <chapitre nb="2" titre="titre du chapitre 2">
  	<section nb="1" titre="titre de la section 1" />
  	<section nb="2" titre="titre de la section 2" />
  </chapitre>
</document>';
//Document à insérer
$xml2 = '<data>
<texte>du texte</texte>
<math type="math" nb="1">2+2=4</math>
<texte> du texte encore du texte...</texte>
</data>';

//Chargement des documents XML dans la RAM
$doc1 = domxml_open_mem($xml1);
$doc2 = domxml_open_mem($xml2);
//Obtenir des objets dom
$objDoc1 = $doc1->document_element();
$objDoc2 = $doc2->document_element();
//Accès à un noeud par nom de balise 
$doc1_sections = $objDoc1->get_elements_by_tagname("section");
//Recherche et insertion dans un noeud précis
foreach($doc1_sections as $section){
	$chapitre_parent = $section->parent_node();
	if ($chapitre_parent->get_attribute('nb') == 1 && $section->get_attribute('nb') == 1){ //recherche par attribut
		$section->append_child($objDoc2->clone_node(true)); //insertion dans le nœud trouvé par clonage
		break;
	}
}
//Afficher le résultat sous forme de chaine XML
echo $doc1->dump_mem();
?>
ça marche comme ça:
On a ouvert deux documents XML dans la mémoire, puis on s'est positionné sur un élément du premier document par recherche de la section ayant l'attribut nb="1" qui appartient au nœud du chapitre ayant l'attribut nb="1".
Une fois l'élément trouvé, le deuxième document est inséré à cet emplacement par clonage qui permet de copier les objets du deuxième document vers le nœud positionné du premier document.

NB; Il existe une autre méthode à explorer, celle d'utiliser la méthode "insert_before()" pour insérer des éléments un par un dans le nœud ciblé.
--------//////----//---//----//////
-------//---//----//---//----//---//
------//////----//////-----//////
-----||--------||--||---||
Prendre le recul n'est pas une perte de temps.


ps: Affrontez moi dans l'arène