Précédent   Forum des professionnels en informatique > PHP > Langage > Fichiers
Fichiers Forum d'entraide sur les fichiers avec PHP. Avant de poster -> FAQ fichiers et Sources fichiers
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 16/11/2010, 12h53   #1
Invité de passage
 
Inscription : juin 2005
Messages : 31
Détails du profil
Informations forums :
Inscription : juin 2005
Messages : 31
Points : 1
Points : 1
Par défaut Concaténation contenus fichiers xml

Bonjour à tous,

Une application tierce (dont je ne peux rien modifier car prestataire extérieur) génére 2 fichiers xml par dossiers traités (un fichier entête et un fichier détail). Seul la 1ère lettre dans le nom de ces deux fichiers changent (Exxxx.xml pour entête et Dxxxx.xml pour détail). Ensuite, tous les fichiers sont copiés dans un répertoire unique. On retrouve dans ce répertoire :
Exxxx1.xml
Dxxxx1.xml
Exxxx2.xml
Dxxxx2.xml
et ainsi de suite en fonction du nombre de dossiers traités.

Je dois boucler sur ce répertoire et concaténer les deux fichiers xml qui appartiennent au même dossier (concaténer Exxxx1.xml avec Dxxxx1.xml).
J'ai réalisé un code qui fonctionne mais je pense qu'il y a moyen de faire mieux. Voici mon code :

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
 
<?php
//Cette fonction va permettre d'écrire dans un fichier de LOG.
function ecrire_log($str_log) {
    $ddmmyyhhmmss = date("d-m-Y H:i:s");
    $a_ecrire = "[".$ddmmyyhhmmss." : ]" . $str_log . "  " ."\r\n";
    $filename = "log/concat_xml_ap.log";
    fwrite(fopen($filename, 'a+'), $a_ecrire);
}
// Fonction qui permet d'ouvrir un fichier et d'enrichir le fichier temporaire
function concat_xml($fichier,$fichier_tmp) {
	if (is_file($fichier)) {
		if ($TabFich = file($fichier)) {
			for($j = 0; $j < count($TabFich); $j++) {
				// ouverture du fichier en écriture
				$fp = fopen($fichier_tmp,"a");
				fputs($fp, "$TabFich[$j]");
				fclose($fp);
			}
		}
	}
	else {
		// On écrit dans le log
		ecrire_log("ERREUR ! $fichier n'est pas un fichier xml !");
	}
}
 
// Déclaration fichier temporaire pour la concaténation
$fichier_tmp = "concat_xml_ap.xml";
 
// On déclare 2 tableaux qui contiendront respectivement les fichires d'entête et les fichiers détails des flux AP
$tableau_entete = array(); 
$tableau_detail = array();
 
// On ouvre le dossier que l'on doit traiter
$dossier = opendir ('.');  
	while ($fichier = readdir ($dossier)) { 
		if ($fichier != '.' && $fichier != '..') { 
			// on stocke le nom des fichiers entetes dans un tableau
			if (preg_match("/^E/", $fichier)) {
				$tableau_entete[] = $fichier;
			}  
			// on stocke le nom des fichiers detail dans un tableau
			if (preg_match("/^D/", $fichier)) {
				$tableau_detail[] = $fichier;
			}
		}  
	}
closedir ($dossier);  
 
// Compte le nombre de fichiers pour chaque tableau
$nbfichiers_entete = count($tableau_entete); 
$nbfichiers_detail = count($tableau_detail);
 
// Si le nombre de fichiers est identique entre les 2 tableaux (même nombre de fichiers entête que détails, c'est bon)	
if ($nbfichiers_entete == $nbfichiers_detail) {
   // On écrit dans le log
   ecrire_log("Le nombre de fichiers entête est identique au nombre de fichiers détails.");
   // On effectue un tri sur les entrées du tableau
   sort($tableau_entete);
   sort($tableau_detail);
	   // On boucle sur le nombre de fichiers
	   for ($i=0; $i<$nbfichiers_entete; $i++){
			// On vérifie que nom du lot entre le fichier entete et le fichier détail est identique
			$entete = substr("$tableau_entete[$i]",1,20);
			$detail = substr("$tableau_detail[$i]",1,20);
			// Les 3 = permettent de vérifier que les valeurs sont de même type et identique
			if ($entete === $detail) {
				concat_xml($tableau_entete[$i],$fichier_tmp);
				concat_xml($tableau_detail[$i],$fichier_tmp);
				//On copie les fichiers qui ont servi à la concaténation dans un autre répertoire
				rename($tableau_entete[$i],"sav_xml/$tableau_entete[$i]"); 
				rename($tableau_detail[$i],"sav_xml/$tableau_detail[$i]");
				rename($fichier_tmp,$tableau_detail[$i]);
			}
			else {
				// On écrit dans le log
				ecrire_log("Le fichier $tableau_entete[$i] est different du fichier $tableau_detail[$i].");
				//On copie les fichiers en erreur dans un autre répertoire
				rename($tableau_entete[$i],"ko_xml/$tableau_entete[$i]"); 
				rename($tableau_detail[$i],"ko_xml/$tableau_detail[$i]");
		   }
	  }
}
else {
	// On écrit dans le log
	ecrire_log("ERREUR ! Il n'y a pas le même nombre de fichiers entete et detail.");
} 
?>
Tout fonctionne, mais quelque chose me gêne et je vais essayer de vous l'expliquer. Mes 2 tableaux sont triés. J'ai donc :

tableau_entete : Exxxx1.xml puis Exxxx2.xml .... etc
tableau_detail : Dxxxx1.xml puis Exxxx2.xml ....ect

Mon problème est le suivant si j'ai :
tableau_entete : Exxxx1.xml puis Exxxx3.xml (le n° 2 a disparu)
tableau_detail : Dxxxx1.xml puis Dxxxx2.xml

La concaténation va fonctionner pour Exxx1 et Dxxx1.xml. Mais pour les autres, du fait qu'il manque Exxxx2.xml tout est décalé et la condition d'égalité n'est plus respecté. Or, Exxxx3.xml existe avec Dxxxx3.xml. Comment faire pour continuer à concaténer lorsque l'entête et le détail sont présent malgré un décalage ?

Est-ce assez claire ou pas ?

Merci pour vos conseils et retour.
Cordialement,
nicoweb371 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 16/11/2010, 20h18   #2
Expert Confirmé
 
Avatar de Séb.
 
Inscription : mars 2005
Messages : 2 813
Détails du profil
Informations personnelles :
Âge : 34
Localisation : France

Informations professionnelles :
Secteur : High Tech - Opérateur de télécommunications

Informations forums :
Inscription : mars 2005
Messages : 2 813
Points : 3 435
Points : 3 435
Code :
1
2
tableau_entete : Exxxx1.xml puis Exxxx2.xml .... etc
tableau_detail : Dxxxx1.xml puis Exxxx2.xml ....ect
Un algo :

Code :
1
2
3
4
5
6
foreach ( $tableau_entete as $fichier_entete ) {
    $fichier_detail = 'D' . substr($fichier_entete, 1) ;
    if ( in_array($fichier_detail, $tableau_detail) ) {
        concatener_fichiers($fichier_entete, $fichier_detail) ;
    }
}
__________________
Un problème exposé clairement est déjà à moitié résolu
Keep It Smart and Simple
Séb. est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 17/11/2010, 07h50   #3
Invité de passage
 
Inscription : juin 2005
Messages : 31
Détails du profil
Informations forums :
Inscription : juin 2005
Messages : 31
Points : 1
Points : 1
Citation:
Envoyé par Séb. Voir le message
Code :
1
2
tableau_entete : Exxxx1.xml puis Exxxx2.xml .... etc
tableau_detail : Dxxxx1.xml puis Exxxx2.xml ....ect
Un algo :

Code :
1
2
3
4
5
6
foreach ( $tableau_entete as $fichier_entete ) {
    $fichier_detail = 'D' . substr($fichier_entete, 1) ;
    if ( in_array($fichier_detail, $tableau_detail) ) {
        concatener_fichiers($fichier_entete, $fichier_detail) ;
    }
}
Salut et Merci.

C'est exactement ce que je cherchais à faire, m'indiquer si il trouve ou pas la même occurrence dans le nom des fichiers. Mais il me reste un petit problème avec cette boucle, c'est qu'il concatène tous les fichiers dans un seul et unique XML. Or, je dois concaténer dans un même fichier, les couples ayant la même occurrence (Exxx1.xml concaténer avec Dxxx1.xml donne D_final_xxx1.xml, idem avec Exxx2 ...).

Une idée ? Je cherche également de mon côté.

@+ tard
nicoweb371 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 17/11/2010, 08h06   #4
Invité de passage
 
Inscription : juin 2005
Messages : 31
Détails du profil
Informations forums :
Inscription : juin 2005
Messages : 31
Points : 1
Points : 1
Autant pour moi !
J'ai trouvé !

Merci encore !
nicoweb371 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 17/11/2010, 08h31   #5
Invité de passage
 
Inscription : juin 2005
Messages : 31
Détails du profil
Informations forums :
Inscription : juin 2005
Messages : 31
Points : 1
Points : 1
Encore moi !

Il me reste un tout petit problème à régler. Avec la boucle actuelle, je vérifie si j'ai une correspondance entre le fichier entete et le tableau detail, mais comment faire également l'inverse ? C'est à dire j'ai le fichier detail mais pas la correspondance d'un fichier entete...

Merci pour votre aide.
@+ tard

Voici le nouveau code source modifié grâce à l'aide Séb.
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
 
<?php
//Cette fonction va permettre d'écrire dans un fichier de LOG.
function ecrire_log($str_log) {
    $ddmmyyhhmmss = date("d-m-Y H:i:s");
    $a_ecrire = "[".$ddmmyyhhmmss." : ]" . $str_log . "  " ."\r\n";
    $filename = "log/concat_xml_ap.log";
    fwrite(fopen($filename, 'a+'), $a_ecrire);
}
// Fonction qui permet d'ouvrir un fichier et d'enrichir le fichier temporaire
function concat_xml($fichier,$fichier_tmp) {
	if (is_file($fichier)) {
		if ($TabFich = file($fichier)) {
			for($j = 0; $j < count($TabFich); $j++) {
				// ouverture du fichier en écriture
				$fp = fopen($fichier_tmp,"a");
				fputs($fp, "$TabFich[$j]");
				fclose($fp);
			}
		}
	}
	else {
		// On écrit dans le log
		ecrire_log("ERREUR ! $fichier n'est pas un fichier xml !");
	}
}
 
// Déclaration fichier temporaire pour la concaténation
$fichier_tmp = "concat_xml_ap.xml";
 
// On déclare 2 tableaux qui contiendront respectivement les fichires d'entête et les fichiers détails des flux AP
$tableau_entete = array(); 
$tableau_detail = array();
 
// On ouvre le dossier que l'on doit traiter
$dossier = opendir ('.');  
	while ($fichier = readdir ($dossier)) { 
		if ($fichier != '.' && $fichier != '..') { 
			// on stocke le nom des fichiers entetes dans un tableau
			if (preg_match("/^E/", $fichier)) {
				$tableau_entete[] = $fichier;
			}  
			// on stocke le nom des fichiers detail dans un tableau
			if (preg_match("/^D/", $fichier)) {
				$tableau_detail[] = $fichier;
			}
		}  
	}
closedir ($dossier);  
 
// Compte le nombre de fichiers pour chaque tableau
$nbfichiers_entete = count($tableau_entete); 
$nbfichiers_detail = count($tableau_detail);
 
// Si le nombre de fichiers est identique entre les 2 tableaux (même nombre de fichiers entête que détails, c'est bon)	
if ($nbfichiers_entete == $nbfichiers_detail) {
   // On écrit dans le log
   ecrire_log("Le nombre de fichiers entête est identique au nombre de fichiers détails.");
   // On effectue un tri sur les entrées du tableau
   sort($tableau_entete);
   sort($tableau_detail);
   // On boucle sur le nombre de fichiers
   foreach ( $tableau_entete as $fichier_entete ) {
		$fichier_detail = 'D' . substr($fichier_entete, 1) ;
		if ( in_array($fichier_detail, $tableau_detail) ) {
			// On écrit dans le log
			ecrire_log("Correspondance trouvé entre le fichier entete $fichier_entete et le fichier detail $fichier_detail.");
			echo "Trouvé<br />";
			concat_xml($fichier_entete,$fichier_tmp);
			concat_xml($fichier_detail,$fichier_tmp);
			//On copie les fichiers qui ont servi à la concaténation dans un autre répertoire
			rename($fichier_entete,"sav_xml/$fichier_entete"); 
			rename($fichier_detail,"sav_xml/$fichier_detail");
			rename($fichier_tmp,$fichier_detail);
		}
		else {
			// On écrit dans le log
			ecrire_log("Correspondance non trouvé entre le fichier entete $fichier_entete et le fichier detail $fichier_detail.");
			echo "Pas trouvé<br />";
			//On copie les fichiers en erreur dans un autre répertoire
			rename($fichier_entete,"ko_xml/$fichier_entete"); 
			rename($fichier_detail,"ko_xml/$fichier_detail");
		}
	}
}
else {
	// On écrit dans le log
	ecrire_log("ERREUR ! Il n'y a pas le même nombre de fichiers entete et detail.");
} 
?>
Merci.
nicoweb371 est déconnecté   Envoyer un message privé Réponse avec citation 01
Vieux 17/11/2010, 11h41   #6
Invité de passage
 
Inscription : juin 2005
Messages : 31
Détails du profil
Informations forums :
Inscription : juin 2005
Messages : 31
Points : 1
Points : 1
Bon, en faite j'ai laissé tomber en PHP et j'ai fait cela en Shell, plus rapide et moins de ligne de code !

Merci quand même.

@+
nicoweb371 est déconnecté   Envoyer un message privé Réponse avec citation 01
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 18h29.


 
 
 
 
Partenaires

Hébergement Web