在PHP中,如何根据变量获取XML属性?

时间:2012-04-16 04:15:50

标签: php xml variables

我正在检索这样的文件(来自互联网档案馆):

<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;

3 个答案:

答案 0 :(得分: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)');

答案 1 :(得分:0)

$elem->file[$chosenThumb]会从主文件[]中提供$chosenThumb'元素而不是过滤(用于缩略图)文件[],对吧?

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']);

答案 2 :(得分: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'];
    

/ edit:但我推荐那个人的解决方案,使用XPath。方式更容易。