Précédent   Forum des professionnels en informatique > PHP > Bibliothèques et frameworks > XML > DOM
DOM Forum d'entraide pour l'extension DOM permettant de manipuler des documents XML en PHP 5 (approche DOM). Avant de poster -> tutoriels DOM
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 08/04/2011, 11h42   #1
Futur Membre du Club
 
Femme
Développeur Web
Inscription : avril 2009
Messages : 50
Détails du profil
Informations personnelles :
Sexe : Femme
Localisation : France

Informations professionnelles :
Activité : Développeur Web

Informations forums :
Inscription : avril 2009
Messages : 50
Points : 18
Points : 18
Par défaut Parsage de sitemap

Bonjour,

Je sollicite votre aide pour un soucis que j'essaye de résoudre depuis plusieurs jours en vain...
Je suis en train de parser un de mes sitemap dans le but de détecter les liens morts et donc de purger le xml. Voila un exemple du xml à parser
Code :
1
2
3
4
5
6
<url>
  <loc>http://mon-url-a-tester</loc>
  <lastmod>....</lastmod>
  <changefreq>.....</changefreq>
  <priority>....</priority>
</url
et voilà ce que j'ai tenté
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
 
$listeUrl = $dom->getElementsByTagName('url');
$listeLoc = $dom->getElementsByTagName('loc');
$i=0;
foreach($listeUrl as $url)
{
	$valeur = $listeLoc->item($i)->nodeValue;
	$test_url = @get_headers($valeur,1);
	if(strstr($test_url[0], '404'))
	{
		$url->parentNode->removeChild($url);
	}
	elseif(isset($test_url[1]) && strstr($test_url[1], '404'))
	{
		$url->parentNode->removeChild($url);
	}
	$i++;
}
Mon objectif et de supprimer chaque bloc <url> qui répond avec une erreur 404. Ça ça fonctionne mais un problème se pose quand deux (ou plus) bloc à supprimer se suivent. En effet le test étant dans un foreach, le fait de supprimer un bloc fait "remonter" le code d'un cran et du coup le test n'est plus indexé au bon endroit. Je ne sais pas si je suis très claire.
Pour remédier à ça j'ai décidé de marquer les bloc à supprimer d'un attribut comme ceci
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
 
$listeUrl = $dom->getElementsByTagName('url');
$listeLoc = $dom->getElementsByTagName('loc');
$i=0;
foreach($listeUrl as $url)
{
	$valeur = $listeLoc->item($i)->nodeValue;
	$test_url = @get_headers($valeur,1);
	if(strstr($test_url[0], '404'))
	{
		$url->setAttribute('todo', 'supprimer');
	}
	elseif(isset($test_url[1]) && strstr($test_url[1], '404'))
	{
		$url->setAttribute('todo', 'supprimer');
	}
        $i++;
}
$listeTest = $dom->getElementsByTagName('url');
foreach($listeTest as $test)
{
	if($test->hasAttribute('todo'))
	{
		if(($test->getAttribute('todo')) == "supprimer")
		{
			$test->parentNode->removeChild($test);
		}
	}
}
Mais du coup je me retrouve dans la même situation que celle précédente, dès que je supprime un bloc, le test perd son indexation. Du coup j'ai deux questions à poser :
- Est-ce qu'il existerais un moyen de sélectionner tous les blocs ayant comme attribut todo="supprimer" et d'utiliser un while pour tous les supprimer

- Ou bien faut-il procéder d'un autre manière depuis le départ ?

Merci d'avance
titinesaku est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 08/04/2011, 12h47   #2
Modérateur
 
Avatar de Benjamin Delespierre
 
Benjamin Delespierre
Développeur Web
Inscription : février 2010
Messages : 2 984
Détails du profil
Informations personnelles :
Nom : Benjamin Delespierre
Âge : 24
Localisation : France

Informations professionnelles :
Activité : Développeur Web
Secteur : High Tech - Opérateur de télécommunications

Informations forums :
Inscription : février 2010
Messages : 2 984
Points : 5 016
Points : 5 016
Citation:
Est-ce qu'il existerais un moyen de sélectionner tous les blocs ayant comme attribut todo="supprimer" et d'utiliser un while pour tous les supprimer
Yep, avec un DOMXPath. Quelque chose de la forme:
Code :
1
2
3
4
5
6
 
$xpath = new DOMXPath($doc);
$nodes = $xpath->query('//[@todo="supprimer"]');
foreach ($nodes as $node) {
   // ...
}
Devrait faire l'affaire.

Mais c'est ton algo de départ qui est en cause, j'ai fait un test avec ce 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
 
<?php
 
$xml = <<< XML
<?xml version="1.0"?>
<books>
	<book>
		<title>TEST 1</title>
		<foobar>Lorem ipsum sit amet...</foobar>
		<foobar>Lorem ipsum sit amet...</foobar>
	</book>
	<book>
		<title>TEST 2</title>
		<foobar>Lorem ipsum sit amet...</foobar>
	</book>
	<book>
		<title>TEST 3</title>
		<foobar>Lorem ipsum sit amet...</foobar>
		<foobar>Lorem ipsum sit amet...</foobar>
		<foobar>Lorem ipsum sit amet...</foobar>
	</book>
</books>
XML;
 
$doc = new DOMDocument;
$doc->loadXML($xml);
 
foreach ($doc->getElementsByTagName('foobar') as $node) {
	$node->parentNode->removeChild($node);
}
 
header('Content-Type: text/xml');
echo $doc->saveXML();
et il s'avère que seul le dernier child de chaque node book est effectivement supprimé.
En passant par un domxpath, ça fonctionne correctement:
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
 
<?php
 
$xml = <<< XML
<?xml version="1.0"?>
<books>
	<book>
		<title>TEST 1</title>
		<foobar>Lorem ipsum sit amet...</foobar>
		<foobar>Lorem ipsum sit amet...</foobar>
	</book>
	<book>
		<title>TEST 2</title>
		<foobar>Lorem ipsum sit amet...</foobar>
	</book>
	<book>
		<title>TEST 3</title>
		<foobar>Lorem ipsum sit amet...</foobar>
		<foobar>Lorem ipsum sit amet...</foobar>
		<foobar>Lorem ipsum sit amet...</foobar>
	</book>
</books>
XML;
 
$doc = new DOMDocument;
$doc->loadXML($xml);
 
$xpath = new DOMXPath($doc);
 
foreach ($xpath->query('//foobar') as $node) {
	$node->parentNode->removeChild($node);
}
 
header('Content-Type: text/xml');
echo $doc->saveXML();
__________________
A la recherche d'un framework MVC facile a prendre en main ? Essayez Axiom
Nouveau: la référence d'Axiom est disponible sur GitHub (je la peaufine en ce moment même).

Un problème correctement identifié est à moitié résolu, évitez de poster l'intégralité de votre code avec pour seule explication "ça ne marche pas...".
Pour identifier correctement vos problèmes PHP, utilisez la gestion des erreurs et xdebug.

Les boutons et existent, servez-vous en
Benjamin Delespierre est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 04h26.


 
 
 
 
Partenaires

Hébergement Web