2010-03-05 5 views
2

J'apprends à analyser XML avec le langage XML simple de PHP. Mon code est:Analyse XML avec simpleXML de PHP

<?php 
$xmlSource = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?> <Document xmlns=\"http://www.apple.com/itms/\" artistId=\"329313804\" browsePath=\"/36/6407\" genreId=\"6507\"> <iTunes> myApp </iTunes> </Document>"; 

$xml = new SimpleXMLElement($xmlSource); 

$results = $xml->xpath("/Document/iTunes"); 
foreach ($results as $result){ 
echo $result.PHP_EOL; 
} 

print_r($result); 
?> 

Lorsque ce programme s'exécute, il renvoie un écran vide, sans erreur. Si je supprime tous les attributs de la balise de document, elle renvoie:

myApp SimpleXMLElement Object ([0] => myApp) 

Quel est le résultat attendu.

Qu'est-ce que je fais mal? Notez que je n'ai aucun contrôle sur la source XML, puisqu'elle provient d'Apple.

Répondre

2

Pour la partie sur l'espace de nom par défaut, lisez fireeyedboy's answer. Comme mentionné, vous devez enregistrer un espace de noms si vous voulez utiliser XPath sur les nœuds qui se trouvent dans l'espace de noms par défaut. Cependant, si vous n'utilisez pas xpath(), SimpleXML possède sa propre magie qui sélectionne automatiquement l'espace de noms par défaut.

$xmlSource = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?> <Document xmlns=\"http://www.apple.com/itms/\" artistId=\"329313804\" browsePath=\"/36/6407\" genreId=\"6507\"> <iTunes> myApp </iTunes> </Document>"; 

$Document = new SimpleXMLElement($xmlSource); 

foreach ($Document->iTunes as $iTunes) 
{ 
    echo $iTunes, PHP_EOL; 
} 
+0

Fantastique! Pouvez-vous me montrer la documentation expliquant cette fonctionnalité en détail? – SooDesuNe

+0

Eh bien, c'est la chose: au meilleur de ma connaissance, il n'y a pas de doc sur la façon dont les espaces de noms par défaut sont gérés. –

0

Cette ligne:

print_r($result); 

est en dehors de la boucle foreach. Peut-être que vous devriez essayer

print_r($results); 

à la place.

0

Semble que si vous utilisez le caractère générique (//) sur xpath cela fonctionnera. En outre, je ne sais pas pourquoi, mais si vous supprimez l'attribut namespace (xmlns) de l'élément Document, votre code actuel fonctionnera. Peut-être parce qu'un préfixe n'est pas défini? Quoi qu'il en soit, le suivant devrait fonctionner:

$results = $xml->xpath("//iTunes"); 
foreach ($results as $result){ 
echo $result.PHP_EOL; 
} 
9

Votre fichier XML contient un espace de noms par défaut. Pour que votre requête xpath fonctionne, vous devez enregistrer cet espace de noms et utiliser le préfixe d'espace de noms sur chaque élément xpath que vous interrogez (à condition que ces éléments appartiennent tous au même espace de noms, comme dans votre exemple):

$xml = new SimpleXMLElement($xmlSource); 

// register the namespace with some prefix, in this case 'a' 
$xml->registerXPathNamespace('a', 'http://www.apple.com/itms/'); 

// then use this prefix 'a:' for every node you are querying 
$results = $xml->xpath('/a:Document/a:iTunes'); 

foreach($results as $result) 
{ 
    echo $result . PHP_EOL; 
}