For循环不显示XML文件中所有行的数据

时间:2019-06-03 06:50:56

标签: php html xml

我有一个具有以下结构的XML文件:

<item>
  <title></title>
  <link></link>
  <description></description>
  <content:encode></content:encode>
  <pubDate></pubDate>
  <author></author>
  <guid></guid>
  <dc:date></dc:date>
</item>

我正在显示上面的特定数据。

<?php
$importPathHref="test.xml";
$importBuffer = implode("",file($importPathHref));
$dom = new DomDocument();
$dom->loadXML($importBuffer);
$xpath = new DOMXpath($dom);
$items = $xpath->query("//item");
$results = parse($items);

$col = $dom->getElementsByTagName('item');

$i = 0;
foreach( $col as $item ){
    $blogTitle=$item->childNodes[1]->nodeValue;
    $blogImage=$item->childNodes[5]->nodeValue;
    $blogDate=$item->childNodes[9]->nodeValue; 
    $blogAuthor=$item->childNodes[11]->nodeValue;
        
        
    if(++$i > 4) break;
        
?>

<?php if ($i == 1) { ?>
  <div class="item__card">
    <div class="item__cardImg">
      <?php echo $blogImage; ?>
    </div>
    <div class="item__cardContent">
      <span class="author"><?php echo $blogAuthor; ?></span>
      <span class="title"><?php echo $blogTitle; ?></span>
      <span class="date"><?php echo $blogDate; ?></span>
    </div>
  </div>
<?php } ?>

<?php } ?>
<!-- end for loop -->

我正在尝试运行for以获得结果(注意if(++$i > 4) break;)。其他所有内容都可以正常运行,但是$blogAuthor仅显示第一项。最后三个结果的作者为空。不确定为什么?

2 个答案:

答案 0 :(得分:3)

您访问childNodes中的$item很危险。

它将适用于这样的事情。

<item>
  <title>Title</title>
  <link>Link</link>
  <description>Desc</description>
  <content:encode>Encode</content:encode>
  <pubDate>Date</pubDate>
  <author>Author</author>
  <guid>Guid</guid>
  <dc:date>Date</dc:date>
</item>

但是会失败

<item>
  <title>Title</title>
  <link>Link</link>
  <description>Desc</description>
  <content:encode>Encode</content:encode>
  <pubDate>Date</pubDate><author>Author</author>
  <guid>Guid</guid>
  <dc:date>Date</dc:date>
</item>

这是因为childnodes与元素之间的空格匹配。如果缺少一个字符(例如<pubDate></pubDate><author></author>之间没有空格),则计数将失败。

使用children

会更好
    $blogTitle=$item->children[0]->nodeValue;
    $blogImage=$item->children[2]->nodeValue;
    $blogDate=$item->children[4]->nodeValue; 
    $blogAuthor=$item->children[5]->nodeValue;

使用dom查询甚至更好

    $blogTitle=$item->getElementsByTagName('title')->item(0)->nodeValue;
    $blogImage=$item->getElementsByTagName('description')->item(0)->nodeValue;
    $blogDate=$item->getElementsByTagName('pubDate')->item(0)->nodeValue; 
    $blogAuthor=$item->getElementsByTagName('author')->item(0)->nodeValue;

答案 1 :(得分:0)

项子节点的索引可能不同。它们可以具有不同的顺序,其他节点(包括注释)或只是一些换行符。

默认情况下,节点之间的空格将解析为文本节点。这使库可以保存相同的XML。您可以设置DOMDocument::preserveWhiteSpace属性来避免它。

您开始使用Xpath,但后来忽略了结果。 Xpath表达式使您可以更有针对性地访问XML节点。

$document = new DOMDocument();
$document->loadXML($xml);
$xpath = new DOMXpath($document);
// fetch all item nodes and limit to the first 4
$items = $xpath->evaluate("(//item)[position() < 5]");

foreach ($items as $index => $item) {
    // cast the first title child node to string - empty if not found
    $blogTitle = $xpath->evaluate('string(title)', $item);

    // ...   
}