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 关于#vscode#的问题:ESP32开发板对接MQTT实现小灯泡的开关
  • ¥15 TMC2209串口模式下读取不到寄存器的值串口助手蓝色字体是发过去的消息,绿色字体是收到的消息,第二行发送读取寄存器的指令但是没有读取到寄存器的值串口助手如下图:接线如下图,如何解决?
  • ¥15 高通安卓11提取完整线刷包软件,或者优博讯dt50顺丰刷机包
  • ¥20 C,有个译码器,换了信道就跑不出原来数据
  • ¥15 MIMIC数据库安装问题
  • ¥60 基于JTag协议开发Fpga下载器上位机,哪位大🐂有偿指导?
  • ¥20 全书网Java爬取数据
  • ¥15 怎么获取红包封面的原始链接,并且获取红包封面序列号
  • ¥100 微信小程序跑脚本授权的问题
  • ¥100 房产抖音小程序苹果搜不到安卓可以付费悬赏