2015-09-25 48 views
1

我試圖用PHP解析XML,但是我遇到了問題。解析嵌套XML節點的屬性值

所以XML看起來像這樣(簡體)

<weatherdata> 
<forecast> 
<tabular> 
    <time from="2015-09-25T20:00:00" to="2015-09-25T23:00:00" period="3"> 
     <symbol number="4" numberEx="4" name="Cloudy" var="04" /> 
    </time> 
    <time from="2015-09-25T23:00:00" to="2015-09-26T05:00:00" period="0"> 
     <symbol number="9" numberEx="46" name="Light rain" var="46" /> 
    </time> 

.....

我能夠從值加載所有的時間>是這樣的:

foreach($xml->forecast->tabular as $forecastItem){ 
    $attr = $forecastItem->attributes(); 
    $froms[] = $attr['from'];  
} 

但後來我試圖加載這樣的符號的名稱屬性:

foreach($xml->forecast->tabular as $forecastItem){ 
    $attr = $forecastItem->attributes(); 
    $froms[] = $attr['from']; 
    $attr2 = $forecastItem->symbol->attributes(); 
    $names[] = $attr2['name']; 
} 

它顯示我main()節點不存在的錯誤。基本上我想要做的就是將所有名稱加載到一個數組中,就像來自froms一樣。

回答

1

您應該使用$xml->forecast->tabular->children()遍歷XML的孩子:

<?php 

$data = '<weatherdata> 
<forecast> 
<tabular> 
    <time from="2015-09-25T20:00:00" to="2015-09-25T23:00:00" period="3"> 
     <symbol number="4" numberEx="4" name="Cloudy" var="04" /> 
    </time> 
    <time from="2015-09-25T23:00:00" to="2015-09-26T05:00:00" period="0"> 
     <symbol number="9" numberEx="46" name="Light rain" var="46" /> 
    </time> 
    </tabular> 
    </forecast> 
    </weatherdata>'; 

$xml = simplexml_load_string($data); 

$froms = array(); 
$names = array(); 

foreach($xml->forecast->tabular->children() as $forecastItem){ 
    $attr = $forecastItem->attributes(); 
    $froms[] = $attr['from']; 
    $attr2 = $forecastItem->symbol->attributes(); 
    $names[] = $attr2['name']; 
} 

print_r($froms); 
print_r($names); 

Output

Array 
(
    [0] => SimpleXMLElement Object 
     (
      [0] => 2015-09-25T20:00:00 
     ) 

    [1] => SimpleXMLElement Object 
     (
      [0] => 2015-09-25T23:00:00 
     ) 

) 
Array 
(
    [0] => SimpleXMLElement Object 
     (
      [0] => Cloudy 
     ) 

    [1] => SimpleXMLElement Object 
     (
      [0] => Light rain 
     ) 

) 
+0

@Alan謝謝,我剛剛也注意到了,好像我們在同一時間編輯它。 –

+0

沒問題,重要的是,它的現予以更正。 :) –

2

你得到完整的錯誤信息是:

警告:主要( ):節點不再存在於...

接着下面的代碼的行數:

$attr2 = $forecastItem->symbol->attributes(); 

它可能不是很清楚,你有什麼錯誤實際上是約。爲了更好地理解它,您必須瞭解一下您在此使用的SimpleXmlElement的內部工作。

如果你被它的名稱訪問一個子元素,爲examle喜歡這裏的<symbol>元素:

$forecastItem->symbol 

SimpleXML擴展將創建節點上即時爲暫時的,沒有這樣的時候子元素已經存在。這樣做是爲了在飛行中添加它。例如:

$forecastItem->symbol = 'hello world!'; 

echo $forecastItem->asXML(); 

將顯示:

<tabular> 
    <time from="2015-09-25T20:00:00" to="2015-09-25T23:00:00" period="3"> 
     <symbol number="4" numberEx="4" name="Cloudy" var="04"/> 
    </time> 
    <time from="2015-09-25T23:00:00" to="2015-09-26T05:00:00" period="0"> 
     <symbol number="9" numberEx="46" name="Light rain" var="46"/> 
    </time> 
<symbol>hello world!</symbol></tabular> 
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 

而這也解釋了爲什麼您的代碼不起作用。由於符號元素只是暫時性的,而你沒有設置它,SimpleXML只是試圖告訴你,這個節點不再存在。這是正確的,當你試圖讀取一個不存在的節點的屬性:

$forecastItem->symbol->attributes(); // no write, but a read operation 

因此,然後工作,預期如果節點存在如這個現有的符號元素:

$forecastItem->time->symbol->attributes(); 

這很可能是您在編寫代碼時位於文檔樹中不同位置的標誌。

+0

非常感謝您的澄清 – Jachym