2014-10-30 27 views
2

让我先说我不熟悉解析XML和/或编写PHP。我一直在研究和拼凑事情,因为我正在做的事情,但我被卡住了。用PHP的SimpleXML检测空的XML节点

我试图创建一个基本的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(),以及没有任何工作

+0

试过'if(count($ guid)== 0)'? – 2014-10-30 17:36:10

+0

刚刚做过 - 它返回相同的东西。 – 2014-10-30 18:31:33

+0

这就是为什么XML很糟糕。空可以是空对象,空字符串或空列表,它们都表示为''。尽可能避免它。 – Rudie 2014-11-01 18:36:39

回答

2

@Wrikken是对的。 XPath是查询XML文档的首选方式。但回答你的问题,你简单的情况下,你可以检查节点值铸造的SimpleXMLElement到字符串为空:

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

而不是强制使用__toString ()'方法,简单地尝试转换它可能会更快:'!(string)$ guid' – Soaku 2017-05-21 17:51:31

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. .是节点的文本内容
+0

我希望我可以做到这一点,但我没有足够的声望点。 :( – 2014-11-06 19:58:01

+0

这似乎是判断一个空白元素(其中open&close是同一个标记)和一个不存在的元素之间区别的唯一方法,其他所有检查都会以相同的方式返回 – 2015-09-30 22:44:10

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) 

这个特殊的规则在PHP手册在案Converting to boolean

您可以利用它来检查您的<guid>元素是否为为空。然而,这里很重要,你特别要求元素。在现有代码:

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

你不能要求一个特定<guid>元素,但所有这一切都是父<item>元素的儿童。这些SimpleXMLElement将对象强制转换为布尔值为真,除非它们包含零个元素(与使用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 
} 

这就回答了你的问题。

+0

在所有事情中,我发现服务器运行在旧版本的PHP之后,所以SimpleXML不会'我不得不重做我的整个文件。 – 2014-11-06 19:57:26