Retirer l'espace de nom XML en utilisant PHP
-
12-09-2019 - |
Question
J'ai un document XML qui ressemble à ceci:
<Data
xmlns="http://www.domain.com/schema/data"
xmlns:dmd="http://www.domain.com/schema/data-metadata"
>
<Something>...</Something>
</Data>
J'analyse les informations en utilisant SimpleXML en PHP. Je traite avec les tableaux et je semble avoir un problème avec l'espace de noms.
Ma question est: Comment puis-je supprimer ces espaces de noms? Je lis les données à partir d'un fichier XML.
Merci!
La solution
Si vous utilisez XPath alors il est une limitation avec XPath et pas look PHP à cette explication sur XPath et namespaces par défaut pour plus d'informations.
Plus précisément son l'attribut xmlns=""
dans le nœud racine qui est l'origine du problème. Cela signifie que vous devrez vous enregistrer l'espace de noms, puis utiliser un QName par la suite de se référer à des éléments.
$feed = simplexml_load_file('http://www.sitepoint.com/recent.rdf');
$feed->registerXPathNamespace("a", "http://www.domain.com/schema/data");
$result = $feed->xpath("a:Data/a:Something/...");
Important :. L'URI utilisé dans l'appel registerXPathNamespace
doit être identique à celui qui est utilisé dans le fichier XML réel
Autres conseils
J'ai trouvé la réponse ci-dessus pour être utile, mais ça n'a pas tout à fait pour moi. Cela a fini par travailler mieux:
// Gets rid of all namespace definitions
$xml_string = preg_replace('/xmlns[^=]*="[^"]*"/i', '', $xml_string);
// Gets rid of all namespace references
$xml_string = preg_replace('/[a-zA-Z]+:([a-zA-Z]+[=>])/', '$1', $xml_string);
Le code PHP suivant détecte automatiquement l'espace de noms par défaut spécifié dans le fichier XML sous l'alias « par défaut ». Pas toutes les requêtes XPath doivent être mis à jour pour inclure le préfixe default:
Donc, si vous voulez lire des fichiers XML plutôt qu'ils contiennent une définition par défaut NS ou ils ne le font pas et que vous voulez interroger tous les éléments Something
, vous pouvez utiliser le code suivant:
$xml = simplexml_load_file($name);
$namespaces = $xml->getDocNamespaces();
if (isset($namespaces[''])) {
$defaultNamespaceUrl = $namespaces[''];
$xml->registerXPathNamespace('default', $defaultNamespaceUrl);
$nsprefix = 'default:';
} else {
$nsprefix = '';
}
$somethings = $xml->xpath('//'.$nsprefix.'Something');
echo count($somethings).' times found';
Pour supprimer complètement l'espace de noms, vous aurez besoin d'utiliser des expressions régulières (RegEx). Par exemple:
$feed = file_get_contents("http://www.sitepoint.com/recent.rdf");
$feed = preg_replace("/<.*(xmlns *= *[\"'].[^\"']*[\"']).[^>]*>/i", "", $feed); // This removes ALL default namespaces.
$xml_feed = simplexml_load_string($feed);
Ensuite, vous avez dépouillé les espaces de noms XML avant de charger le XML (attention à l'expression rationnelle à travers, parce que si vous avez des champs avec quelque chose comme:
<![CDATA[ <Transfer xmlns="http://redeux.example.com">cool.</Transfer> ]]>
Ensuite, il dépouillera les xmlns de l'intérieur du CDATA qui peut conduire à des résultats inattendus.