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?

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

报告相同问题?

悬赏问题

  • ¥15 关于库卡officelite无法与虚拟机通讯的问题
  • ¥15 qgcomp混合物线性模型分析的代码出现错误:Model aliasing occurred
  • ¥100 已有python代码,要求做成可执行程序,程序设计内容不多
  • ¥15 目标检测项目无法读取视频
  • ¥15 GEO datasets中基因芯片数据仅仅提供了normalized signal如何进行差异分析
  • ¥15 小红薯封设备能解决的来
  • ¥100 求采集电商背景音乐的方法
  • ¥15 数学建模竞赛求指导帮助
  • ¥15 STM32控制MAX7219问题求解答
  • ¥20 在本地部署CHATRWKV时遇到了AttributeError: 'str' object has no attribute 'requires_grad'