2012-04-16 60 views
1

我檢索文件像這樣(從互聯網檔案):在PHP中,如何獲得基於變量的XML屬性?

<files> 
    <file name="Checkmate-theHumanTouch.gif" source="derivative"> 
    <format>Animated GIF</format> 
    <original>Checkmate-theHumanTouch.mp4</original> 
    <md5>72ec7fcf240969921e58eabfb3b9d9df</md5> 
    <mtime>1274063536</mtime> 
    <size>377534</size> 
    <crc32>b2df3fc1</crc32> 
    <sha1>211a61068db844c44e79a9f71aa9f9d13ff68f1f</sha1> 
    </file> 
    <file name="CheckmateTheHumanTouch1961.thumbs/Checkmate-theHumanTouch_000001.jpg" source="derivative"> 
    <format>Thumbnail</format> 
    <original>Checkmate-theHumanTouch.mp4</original> 
    <md5>6f6b3f8a779ff09f24ee4cd15d4bacd6</md5> 
    <mtime>1274063133</mtime> 
    <size>1169</size> 
    <crc32>657dc153</crc32> 
    <sha1>2242516f2dd9fe15c24b86d67f734e5236b05901</sha1> 
    </file> 
</files> 

他們可以有任意數量的<file> s,而我只是在尋找那些縮略圖的人。當我找到他們時,我想增加一個計數器。當我瀏覽整個文件時,我想查找中間的縮略圖並返回name屬性。

這裏是我到目前爲止有:

//pop previously retrieved XML file into a variable 
$elem = new SimpleXMLElement($xml_file); 
//establish variable 
$i = 0; 

// Look through each parent element in the file 
foreach ($elem as $file) { 
    if ($file->format == "Thumbnail"){$i++;} 
} 
    //find the middle thumbnail. 
$chosenThumb = ceil(($i/2)-1); 
    //Gloriously announce the name of the chosen thumbnail. 
echo($elem->file[$chosenThumb]['name']);` 

最後的回聲不起作用,因爲它不喜歡有一個變量選擇的XML元素。當我硬編碼時它工作正常。你能猜到我是處理XML文件的新手嗎?

編輯:從下面 弗朗西斯·阿維拉的答案整理我的權利了!:

$sxe = simplexml_load_file($url); 
$thumbs = $sxe->xpath('/files/file[format="Thumbnail"]'); 
$n_thumbs = count($thumbs); 
$middlethumb = $thumbs[(int) ($n_thumbs/2)]; 
$happy_string = (string)$middlethumb[name]; 
echo $happy_string; 
+0

嗨,請使用php.net/dom代替...您可以使用simplexml來做到這一點,是的,但是dom具有與真棒API相同的性能。 $ a = $ doc-> getElementsByTagName(「file」); foreach($ a as $ x)if($ x-> hasAttribute(「name」))... – skyline26 2012-04-16 04:24:28

+0

代碼對我來說看起來不錯 - 當你在echo語句中使用$ chosenThumb而不是hard-編碼?我的猜測是,價值是訪問不存在的索引(例如,如果沒有找到縮略圖,它將是-1這是無效的) – TheOx 2012-04-16 04:26:03

+0

@TheOx如果我使用$ chosenThumb,我什麼也得不到回報。根本沒有錯誤信息。如果我硬編碼它,我會得到我正在尋找的確切結果。在這種情況下,如果我將它設置爲[1],我會回來「CheckmateTheHumanTouch1961.thumbs/Checkmate-theHumanTouch_000001.jpg」 – 2012-04-16 04:31:13

回答

5

使用XPath。

$sxe = simplexml_load_file($url); 
$thumbs = $sxe->xpath('/files/file[format="Thumbnail"]'); 
$n_thumbs = count($thumbs); 
$middlethumb = $thumbs[(int) ($n_thumbs/2)]; 
$middlethumbname = (string) $middlethumb['name']; 

您還可以使用一個XPath表達式做到這一點,如果你不需要總數:

$thumbs = $sxe->xpath('/files/file[format="Thumbnail"][position() = floor(count(*) div 2)]/@name'); 
$middlethumbname = (count($thumbs)) ? $thumbs[0]['name'] : ''; 

的SimpleXML的XPath的方法的侷限性在於它只能返回節點,而不是簡單類型。這就是爲什麼你需要使用$thumbs[0]['name']。如果你使用DOMXPath::evaluate(),你可以這樣做,而不是:

$doc = new DOMDocument(); 
$doc->loadXMLFile($url); 
$xp = new DOMXPath($doc); 
$middlethumbname = $xp->evaluate('string(/files/file[format="Thumbnail"][position() = floor(count(*) div 2)]/@name)'); 
+0

絕對驚人。非常感謝。 – 2012-04-16 04:54:04

0

$elem->file[$chosenThumb]會給$chosenThumb「th元素從主文件[]不過濾(用於縮略圖)文件[],對?

foreach ($elem as $file) { 
    if ($file->format == "Thumbnail"){ 
    $i++; 
    //add this item to a new array($filteredFiles) 
    } 
} 

$chosenThumb = ceil(($i/2)-1); 

//echo($elem->file[$chosenThumb]['name']); 
    echo($filteredFiles[$chosenThumb]['name']); 
+0

哦,是的,好點!發現得好。 – 2012-04-16 04:35:24

0

一些問題:不正確地計算

  • 中的縮略圖。你必須爲這些大拇指保留一個單獨的數組,並使用count來獲得中間數組。
  • file可能需要是{'file'},我不確定PHP如何看待這個。
  • 你沒有一個默認的縮略圖
  • 你應該使用
  • 代碼是這一個:

    $files = new SimpleXMLElement($xml_file); 
    $thumbs = array(); 
    
    foreach($files as $file) 
        if($file->format == "Thumbnail") 
         $thumbs[] = $file; 
    
    $chosenThumb = ceil((count($thumbs)/2)-1); 
    echo (count($thumbs)===0) ? 'default-thumbnail.png' : $thumbs[$chosenThumb]['name']; 
    

/編輯:但我建議那傢伙的解決方案,使用XPath。方式更容易。

+0

非常感謝您提供瞭如此詳盡的評論。如上所述,我最終使用了上面的XPath解決方案。 – 2012-04-16 04:57:29