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

41
demandé sur hakre 2010-12-29 15:50:22

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();
}
66
répondu Tjirp 2012-12-28 05:00:59

De la documentation :

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é par libxml_get_errors(), contient plusieurs propriétés, y compris la message, line et column (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

16
répondu Felix Kling 2015-02-09 21:24:58

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'));
9
répondu admin 2015-07-06 08:14:19

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
    }
}
7
répondu Jkhaled 2014-06-04 10:07:29

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.

2
répondu Francesco Casula 2015-05-08 09:47:57

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.

0
répondu aexl 2018-09-14 12:36:56