使用PHP的SimpleXML检测空XML节点

时间:2014-10-30 17:16:16

标签: php simplexml nodes isnullorempty

首先让我说我不熟悉解析XML和/或编写PHP。我一直在研究和拼凑我正在做的事情,但我被卡住了。

我正在尝试创建一个基本的if / else语句:如果节点不为空,则写入节点的内容。

以下是我正在调用的XML片段:

<channel>
    <item>
      <title>This is a test</title>
      <link />
      <description>Test description</description>
      <category>Test category</category>
      <guid />
    </item>
  </channel>

这是我到目前为止的PHP:

<?php
    $alerts = simplexml_load_file('example.xml');
    $guid = $alerts->channel->item->guid;

    if ($guid->count() == 0) {
    print "// No alert";
}
    else {
        echo "<div class='emergency-alert'>".$guid."</div>";
}

?>

显然,“guid”是一个空节点,但它正在返回:

<div class="emergency-alert"> </div>

我做错了什么? :(

PS,我已经尝试过hasChildren(),但也没有用。

3 个答案:

答案 0 :(得分:3)

@Wrikken是对的。 XPath是查询XML文档的首选方式。但回答您的问题,在您的简单情况下,您可以通过将SimpleXMLElement强制转换为字符串来检查节点值是否为空:

if ( !$guid->__toString() ) {
    print "No alert";
}

答案 1 :(得分:2)

foreach($alerts->xpath("//item/guid[normalize-space(.)!='']") as $guid){
        echo "<div class='emergency-alert'>".$guid."</div>";
}

它做了什么?

  1. xpath:查询xml文档的简单方法
  2. normalize-space:剥离了前导,尾随和重复空格的参数字符串(即:<guid> </guid>不是空字符串,它是' ',但是这一个变成了它到''
  3. .是节点的文本内容

答案 2 :(得分:0)

在PHP中, SimpleXMLElement 表示一个空的XML元素(自闭标签或没有内容的空开/关标签对)转换为布尔值FALSE。这可能有点出乎意料,因为通常PHP中的每个对象都会转换为布尔值TRUE

var_dump((bool) new SimpleXMLElement("<guid/>")); # bool(false)

var_dump((bool) new SimpleXMLElement("<guid></guid>")); # bool(false)

var_dump((bool) new SimpleXMLElement("<guid> </guid>")); # bool(true)

此特殊规则记录在Converting to boolean的PHP手册中。

您可以使用它来检查您拥有的<guid>元素是否为为空。但是在这里它非常重要,你要特别要求这个元素。在您现有的代码中:

$guid = $alerts->channel->item->guid;

您不是要求特定的<guid>元素,而是要求所有父元素<item>元素的子元素。这些 SimpleXMLElement 对象强制转换为布尔值true,除非它们包含零元素(与使用SimpleXMLElement::count()进行比较)。

与此不同的是,如果您通过索引获得第一个<guid>元素,您将获得该索引 NULL SimpleXMLElement 如果元素不存在(也就是说,没有<guid>元素)。

两者 - 不存在的元素NULL或现有的空元素 - 将转换为布尔false,可以在if / else语句中轻松使用:

$guid = $alerts->channel->item->guid[0];
                                    ### zero is the index of the first element
if ((bool) $guid) {
    # non-empty, existing <guid> element
} else {
    # empty or non-existing
}

然后回答你的问题。