1

我正在使用 PHP 和 Xpath 为几个不同的值解析文档。我将 Xpath 查询的结果/匹配项放入数组中。因此,例如,我$prices array像这样构建我的:

$prices = array();
$result = $xpath->query("//div[@class='the-price']");
foreach ($result as $object) {
$prices[] = $object->nodeValue; }

一旦我建立了我的数组,我就会循环并将这些值放入一些 HTML 中,如下所示:

$i = 0;
foreach ($links as $link) {
    echo <<<EOF
<div class="the-product">
    <div class="the-name"><a title="{$names[$i]}" href="{$link}" target="blank">{$names[$i]}</a></div>
    <br />
    <div class="the-image"><a title="{$names[$i]}" href="{$link}" target="blank"><img src="{$images[$i]}" /></a></div>
    <br />
    <div class="the-current-price">Price is: <br> {$prices[$i]}</div>
</div>
EOF;
    $i++; }

问题是,我正在解析的原始文档中的某些项目没有价格,例如,它们甚至不包含<div class='the-price'>,所以我的 Xpath 没有找到值,也没有将值插入$prices array. _ 我最终返回了20 个产品和一个仅包含17 个键/值的数组,导致Notice: Undefined offset整个地方出现错误。

所以我的问题是,我该如何解释缺少键值并丢弃我的数组的项目?我可以在这些项目的数组中插入虚拟值吗?我已经尝试了尽可能多的不同解决方案。主要是我的 foreach 循环中的 IF 语句,但似乎没有任何效果。

谢谢

4

4 回答 4

0

使用显示的代码很难理解 $links 和 $prices 之间的关系。由于您正在构建与 $links 数组没有任何关系的 $prices 数组,因此我不知道您将如何执行此操作。

$links 也是通过 xpath 构建的吗?如果是这样,'the-price' div 是否总是嵌套在用于填充 $links 的 DOM 元素中?

如果是,您可以嵌套您的 xpath 查询以在用于查找链接的查询中查找价格,并使用计数器来匹配两者。

IE

$links_result = $xpath->query('path-to-link')
$i = 0
foreach ($links_result as $link_object) {
    $links[$i] = $link_object->nodeValue;
    // pass $link_object as context reference to xpath query looking for price
    $price_result = $xpath->query('path-to-price-within-link-node', $link_object);
    if (false !== $price_result) {
        $prices[$i] = $price_result->nodeValue;
    } else {
        $prices[$i] = 0; // or whatever value you want to show to indicate that no price was available.
    }
    $i++;
}

显然,那里可能有额外的处理来验证每个链接节点只存在一个价格值等等,但这是基本思想。

于 2012-07-16T19:58:30.933 回答
0

我建议你在你的 html 中寻找一个元素,它总是出现在你的“价格”循环中。找到此对象后,您开始寻找“价格”元素,如果没有,则将空字符串等插入数组。

于 2012-07-16T19:45:07.743 回答
0

如果您不想显示没有附加价格的产品,您可以检查是否$prices[$i]先设置。

foreach($links AS $link){
    if(isset($prices[$i])){
        // echo content
    }
}

或者,如果您想填充它,您可以说是虚拟值

$prices = array_merge($prices,
              array_fill(count($prices), count($links)-count($prices),0));

这将0作为任何剩余值的虚拟值插入。array_fill首先获取数组的第一个索引(所以我们在键的数量之后开始一个$prices),然后我们需要填充多少,所以我们从有多少中减去有多少$prices$links然后我们用虚拟值 0。

或者,您可以在第一个示例中使用相同的逻辑,然后通过说来应用它:

echo isset($prices[$i]) ? $prices[$i] : '0';
于 2012-07-16T19:47:43.170 回答
0

与其直接查找the-price元素,不如查找包含的the-product. 循环这些,然后使用这些节点作为起始上下文进行子查询。这样您就可以获得所有the-product节点,以及拥有它们的节点的价格。

例如

$products = array();
$products = $xpath->query("//div[@class='the-product']");
$found = 0 ;
foreach ($products as $product) {
   $products[$found] = array();
   $price = $xpath->query("//div[@class='the-price']", $product);
   if ($price->length > 0) {
       $products[$found] = $price->item(0)->nodeValue;
   }
   $found++;
}
于 2012-07-16T19:46:23.263 回答