dsjklb0205 2014-03-11 02:59
浏览 36
已采纳

PHP,simplexml_load_string检查string是否为xml

I am writing a script to handle jsonp response. So that I can interpret it, send it to client, and use my own callback in ajax. Anyway, the response from server is json if it is successful. If the request fails, it returns an xml.

I checked some answers before.

Check whether returned file is XML or not

How check if a String is a Valid XML with-out Displaying a Warning in PHP

This answer works fine, my bad.

I write this.

$xml = simplexml_load_string($result,'SimpleXmlElement', LIBXML_NOERROR+LIBXML_ERR_FATAL+LIBXML_ERR_NONE);
if(!$xml){// json}

This gives out warning,

node no longer exist

The warning enters the json response, making it hard to parse.

I know if I suppress the warnings in php, it would work fine, but this is not the answer I want. I want to know, how do I check the string format, without giving out warning. Even in developing environment. I think it's better to solve problem from the root.

Then I used this,

$xml = simplexml_load_string($result,'SimpleXmlElement', LIBXML_NOERROR+LIBXML_ERR_FATAL+LIBXML_ERR_NONE);
if($xml == false){ // json }

This enters the block no matter if the string is xml or json. $xml == false is always evaluated as true.

I think if you can explain to me, the difference between $xml == false and !$xml that would be great. Thanks in advance.

  • 写回答

1条回答 默认 最新

  • douzhuo5671 2014-03-11 03:07
    关注

    Since a way to detect XML without parsing it has been asked for, the following regex should match a valid XML string, at least preliminarily:

    ^(<([a-zA-Z0-9]+)([\s]+[a-zA-Z0-9]+="[a-zA-Z0-9]+")*>([^<]*([^<]*|(?1))[^<]*)*<\/\2>)$
    

    This can be tested here: http://regex101.com/r/mW9aZ5

    However, I still assert that the libxml way is better. :)

    -- Edit 1

    Turns out this is a duplicate of: How check if a String is a Valid XML with-out Displaying a Warning in PHP

    Tjirp's answer in that thread using libxml_use_internal_errors(true); is much more efficient. I suggest using that.

    -- My original answer, which is inefficient

    Edit: This requires iterating through every node in the XML tree calling ->isValid() for each node. ->isValid() ONLY checks the current node. It does not check the entire tree at once, as one would expect. It's also worth noting that the documentation on PHP.net is ambiguous and lacking complete useful usage examples. I've left this here rather than removing it for this reason.

    You can use XMLReader::isValid() to validate that an opened XML file or string actually contains valid XML.

    To load from the $result string itself:

    $xml = new XMLReader();
    $xml->xml($result);
    $xml->setParserProperty(XMLReader::VALIDATE, true);
    $success = true;
    while ($xml->read()) {
        if (!$xml->isValid()) {
            $success = false;
        }
    }
    if ($success) {
        // Return valid response
    } else {
        // Return invalid response
    }
    

    Alternatively, you can also load the XML from from a file on the filesystem:

    $xml = new XMLReader();
    $xml->open($file);
    // Rest of code as above
    

    Regarding if ($xml == false) always evaluating to true, this should never happen unless $xml is always false. Are you sure you didn't unintentionally write if ($xml = false) instead by accident?

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥50 易语言把MYSQL数据库中的数据添加至组合框
  • ¥20 求数据集和代码#有偿答复
  • ¥15 关于下拉菜单选项关联的问题
  • ¥20 java-OJ-健康体检
  • ¥15 rs485的上拉下拉,不会对a-b<-200mv有影响吗,就是接受时,对判断逻辑0有影响吗
  • ¥15 使用phpstudy在云服务器上搭建个人网站
  • ¥15 应该如何判断含间隙的曲柄摇杆机构,轴与轴承是否发生了碰撞?
  • ¥15 vue3+express部署到nginx
  • ¥20 搭建pt1000三线制高精度测温电路
  • ¥15 使用Jdk8自带的算法,和Jdk11自带的加密结果会一样吗,不一样的话有什么解决方案,Jdk不能升级的情况