Как проверить, является ли строка допустимым XML без отображения предупреждения в PHP - PullRequest
45 голосов
/ 29 декабря 2010

Я пытался проверить правильность строки в формате xml, используя эту функцию simplexml_load_string() Документы , но она отображает множество предупреждающих сообщений.

Как проверить, является ли строка допустимым XML, не подавляя (@ в начале ) ошибку и , отображая функцию предупреждения, которая expec

Ответы [ 6 ]

71 голосов
/ 29 декабря 2010

Используйте libxml_use_internal_errors (), чтобы подавить все ошибки XML, и libxml_get_errors (), чтобы потом их перебирать

Простая строка загрузки XML

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();
}
18 голосов
/ 29 декабря 2010

Из документации :

Устранение ошибок XML при загрузке документов - очень простая задача. Используя функциональность libxml, можно подавить все ошибки XML при загрузке документа, а затем выполнить итерацию ошибок.

Объект libXMLError, возвращаемый libxml_get_errors(), содержит несколько свойств, включая message, line и column (положение) ошибки.

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;
    }
}

Ссылка: libxml_use_internal_errors

9 голосов
/ 06 июля 2015

Моя версия такова:

//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);
}

Тесты:

//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'));
8 голосов
/ 04 июня 2014

попробуйте это

//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
    }
}
2 голосов
/ 05 мая 2015

Вот небольшой фрагмент класса, который я написал некоторое время назад:

/**
 * 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);
    }
}

Отлично работает с потоками и vfsStream , а также для целей тестирования.

0 голосов
/ 14 сентября 2018

Case

Время от времени проверяйте доступность XML-канала Google Merchant.

Подача без DTD, поэтому validate() не будет работать.

Решение

// 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 выше содержит количество фактически перечисленных продуктов в файле. Вместо этого вы можете использовать имена тегов.

Logic

Вы можете позвонить getElementsByTagName() по любым другим именам тегов (item Я использовал для Google Merchant, ваш случай может отличаться) или прочитать другие свойства на $dom сам объект. Логика остается той же: вместо проверки наличия ошибок при загрузке файла, я считаю, что на самом деле попытка манипулировать им (или, в частности, проверить, содержит ли он значения, которые вам действительно нужны), была бы более надежной.

Самое важное: в отличие от validate(), для этого в XML не требуется DTD.

...