2014-10-30 22 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