如何在 PHP 中检查字符串是否为有效 XML 而不显示警告

发布于 2024-10-09 17:37:31 字数 329 浏览 6 评论 0原文

我试图使用 simplexml_load_string()< 检查 xml 字符串的有效性em>Docs 功能,但它显示很多警告消息。

如何在开头不使用 @ 的情况下检查字符串是否为有效的 XML 抑制错误和警告?

i was trying to check the validity of a string as xml using the simplexml_load_string()Docs function but it displays a lot of warning messages.

How can I check whether a string is a valid XML without using @ at the beginning to suppress the errors and warnings?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

愛上了 2024-10-16 17:37:31

使用 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 !== false) {
    $errors = libxml_get_errors();

    foreach ($errors as $error) {
        // Display the error how you want here
        print_r($error);
    }

    libxml_clear_errors();
}

Use libxml_use_internal_errors() to suppress all XML errors, and libxml_get_errors() to iterate over them afterwards.

Simple XML loading string

libxml_use_internal_errors(true);

$doc = simplexml_load_string($xmlstr);
$xml = explode("\n", $xmlstr);

if ($doc !== false) {
    $errors = libxml_get_errors();

    foreach ($errors as $error) {
        // Display the error how you want here
        print_r($error);
    }

    libxml_clear_errors();
}
逆光下的微笑 2024-10-16 17:37:31

来自文档

加载文档时处理 XML 错误是一项非常简单的任务。使用 libxml 功能,可以在加载文档时抑制所有 XML 错误,然后迭代错误。

libxml_get_errors() 返回的 libXMLError 对象包含多个属性,包括 messageline 和错误的(位置)。

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

From the documentation:

Dealing with XML errors when loading documents is a very simple task. Using the libxml functionality it is possible to suppress all XML errors when loading the document and then iterate over the errors.

The libXMLError object, returned by libxml_get_errors(), contains several properties including the message, line and column (position) of the error.

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

Reference: libxml_use_internal_errors

因为看清所以看轻 2024-10-16 17:37:31

我的版本是这样的:

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

My version like this:

//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'));
做个ˇ局外人 2024-10-16 17:37:31

试试这个

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

try this one

//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
    }
}
世界等同你 2024-10-16 17:37:31

这是我不久前写的一小部分课程:

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

它可以与流和 vfsStream 配合使用,也可以用于测试目的。

Here a small piece of class I wrote a while ago:

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

It works fine with streams and vfsStream as well for testing purposes.

梦忆晨望 2024-10-16 17:37:31

案例

偶尔检查 Google Merchant XML feed 的可用性。

该 Feed 没有 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包含文件中实际列出的产品数量。您可以改用您的标签名称。

逻辑

您可以在任何对象上调用 getElementsByTagName()其他标签名称(item 我使用的是 Google Merchant,您的情况可能会有所不同),或阅读 $dom 对象本身的其他属性。逻辑保持不变:我相信实际上尝试操作它(或者专门检查它是否包含您实际需要的值)会更可靠,而不是检查加载文件时是否有错误。

最重要的是:与 validate() 不同,这个不要求您的 XML 具有 DTD。

Case

Occasionally check availability of a Google Merchant XML feed.

The feed is without DTD, so validate() won't work.

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 contains a number of how many products are actually listed in the file. You can use your tag names instead.

Logic

You can call getElementsByTagName() on any other tag names (item I used is for Google Merchant, your case may vary), or read other properties on the $dom object itself. The logic stays the same: instead of checking if there were errors when loading the file, I believe actually trying to manipulate it (or specifically check if it contains the values you actually need) would be more reliable.

Most important: unlike validate(), this won't require your XML to have a DTD.

尘世孤行 2024-10-16 17:37:31

解决方案

<?php
/**
* Check XML validity.
* 
* @param string $xmlstr
* @return bool
*/
public function checkXML($xmlstr)
{
    libxml_use_internal_errors(true);
    $doc = simplexml_load_string($xmlstr);
    if (!$doc) {
        $errors = libxml_get_errors();
        if (count($errors)) {
            libxml_clear_errors();
            return false;
        }
    }

    return true;
}

Solution

<?php
/**
* Check XML validity.
* 
* @param string $xmlstr
* @return bool
*/
public function checkXML($xmlstr)
{
    libxml_use_internal_errors(true);
    $doc = simplexml_load_string($xmlstr);
    if (!$doc) {
        $errors = libxml_get_errors();
        if (count($errors)) {
            libxml_clear_errors();
            return false;
        }
    }

    return true;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文