Comment vérifier si une chaîne est un XML valide sans afficher un avertissement en PHP
J'ai essayé de vérifier la validité d'une chaîne de caractères au format xml à l'aide de cette simplexml_load_string()
Docs fonction, mais il affiche beaucoup de messages d'avertissement.
Comment puis-je vérifier si une chaîne est un XML valide sans la suppression (@
au début) l'erreur et affichage d'une fonction d'avertissement que expec
6 réponses
Utilisez libxml_use_internal_errors () pour supprimer toutes les erreurs XML, et libxml_get_errors () pour les parcourir ensuite.
Chaîne de chargement XML simple
libxml_use_internal_errors(true);
$doc = simplexml_load_string($xmlstr);
$xml = explode("\n", $xmlstr);
if (!$doc) {
$errors = libxml_get_errors();
foreach ($errors as $error) {
echo display_xml_error($error, $xml);
}
libxml_clear_errors();
}
Traiter les erreurs XML lors du chargement de documents est une tâche très simple. En utilisant la fonctionnalité
libxml
, Il est possible de supprimer toutes les erreurs XML lors du chargement du document, puis de parcourir les erreurs.Le
libXMLError
objet renvoyé parlibxml_get_errors()
, contient plusieurs propriétés, y compris lamessage
,line
etcolumn
(position) de l'erreur.
libxml_use_internal_errors(true);
$sxe = simplexml_load_string("<?xml version='1.0'><broken><xml></broken>");
if (!$sxe) {
echo "Failed loading XML\n";
foreach(libxml_get_errors() as $error) {
echo "\t", $error->message;
}
}
Référence: libxml_use_internal_errors
Ma version comme ceci:
//validate only XML. HTML will be ignored.
function isValidXml($content)
{
$content = trim($content);
if (empty($content)) {
return false;
}
//html go to hell!
if (stripos($content, '<!DOCTYPE html>') !== false) {
return false;
}
libxml_use_internal_errors(true);
simplexml_load_string($content);
$errors = libxml_get_errors();
libxml_clear_errors();
return empty($errors);
}
Essais:
//false
var_dump(isValidXml('<!DOCTYPE html><html><body></body></html>'));
//true
var_dump(isValidXml('<?xml version="1.0" standalone="yes"?><root></root>'));
//false
var_dump(isValidXml(null));
//false
var_dump(isValidXml(1));
//false
var_dump(isValidXml(false));
//false
var_dump(isValidXml('asdasds'));
Essayez celui-ci
//check if xml is valid document
public function _isValidXML($xml) {
$doc = @simplexml_load_string($xml);
if ($doc) {
return true; //this is valid
} else {
return false; //this is not valid
}
}
Voici un petit morceau de classe que j'ai écrit il y a quelque temps:
/**
* Class XmlParser
* @author Francesco Casula <fra.casula@gmail.com>
*/
class XmlParser
{
/**
* @param string $xmlFilename Path to the XML file
* @param string $version 1.0
* @param string $encoding utf-8
* @return bool
*/
public function isXMLFileValid($xmlFilename, $version = '1.0', $encoding = 'utf-8')
{
$xmlContent = file_get_contents($xmlFilename);
return $this->isXMLContentValid($xmlContent, $version, $encoding);
}
/**
* @param string $xmlContent A well-formed XML string
* @param string $version 1.0
* @param string $encoding utf-8
* @return bool
*/
public function isXMLContentValid($xmlContent, $version = '1.0', $encoding = 'utf-8')
{
if (trim($xmlContent) == '') {
return false;
}
libxml_use_internal_errors(true);
$doc = new DOMDocument($version, $encoding);
$doc->loadXML($xmlContent);
$errors = libxml_get_errors();
libxml_clear_errors();
return empty($errors);
}
}
Cela fonctionne bien avec les flux et vfsStream aussi bien à des fins de test.
Cas
Vérifiez occasionnellement la disponibilité D'un flux XML Google Merchant.
Le flux est sans DTD, donc validate()
ça ne marchera pas.
Solution
// disable forwarding those load() errors to PHP
libxml_use_internal_errors(true);
// initiate the DOMDocument and attempt to load the XML file
$dom = new \DOMDocument;
$dom->load($path_to_xml_file);
// check if the file contents are what we're expecting them to be
// `item` here is for Google Merchant, replace with what you expect
$success = $dom->getElementsByTagName('item')->length > 0;
// alternatively, just check if the file was loaded successfully
$success = null !== $dom->actualEncoding;
length
ci-dessus contient un certain nombre de combien de produits sont effectivement répertoriés dans le fichier. Vous pouvez utiliser vos noms de balises à la place.
Logique
Vous pouvez appeler getElementsByTagName()
sur tout autre nom de balise (item
que j'ai utilisé est pour Google Merchant, votre cas peut varier), ou lire autre propriétés sur l'objet $dom
lui-même. La logique reste la même: au lieu de vérifier s'il y avait des erreurs lors du chargement du fichier, je crois qu'essayer de le manipuler (ou vérifier spécifiquement s'il contient les valeurs dont vous avez réellement besoin) serait plus fiable.
Le plus important: contrairement à validate()
, cela ne nécessitera pas que votre XML ait une DTD.