web-dev-qa-db-fra.com

Comment vérifier si une chaîne est un XML valide sans afficher un avertissement dans PHP

j'essayais de vérifier la validité d'une chaîne en tant que XML en utilisant cette simplexml_load_string()Docs function mais il affiche beaucoup de messages d’avertissement.

Comment puis-je vérifier si une chaîne est un XML valide sans supprimer ( @ au début ) l'erreur et affichant une fonction d'avertissement qui expec

43
jspeshu

Utilisez libxml_use_internal_errors () pour supprimer toutes les erreurs XML et libxml_get_errors () pour les parcourir ultérieurement. 

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();
}
70
Tjirp

Ma version ressemble à 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);
}

Tests:

//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
admin

essaye celui-là

//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
Jkhaled

Voici un petit morceau de classe que j'ai écrit il y a quelque temps:

/**
 * Class XmlParser
 * @author Francesco Casula <[email protected]>
 */
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 très bien avec les flux et vfsStream aussi bien à des fins de test.

2

Cas

Vérifiez occasionnellement la disponibilité d'un flux XML Google Merchant.

Le flux est sans DTD, donc validate() ne fonctionnera 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 above contient un certain nombre de produits réellement 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 autres 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 pense que tenter de le manipuler (ou plus précisément de vérifier 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
aexl