找不到正确的XPath表达式(合并结果)

时间:2011-03-13 17:36:00

标签: php xpath

我正试图从wikipedia获取一系列谚语。

我可以选择:

  • 类别(例如“aanval”,“aap”)
  • 谚语(例如“De aanhouder wint。”)
  • 解释(例如“Wie blijft proberen zijn doel te bereiken,heeft uiteindelijk succes.je moet volhouden。”)

但很难以正确的方式加入他们。我想最终得到一个像:

这样的数组
array(
  0 => array(
    'category' => 'aanval',
    'proverb' => 'De aanval is de beste verdediging.',
    'explanation' => array(
      0 => 'Je kunt in een strijd of ruzie beter zelf actie ondernemen dan afwachten.',
    )
  ),
  1 => array(
    'category' => 'aap',
    'proverb' => 'Al draagt een aap een gouden ring, het is en blijft een lelijk ding.',
    'explanation' => array(
      0 => 'Wie zich mooi aankleedt wordt daarmee zelf nog niet mooi.',
      1 => 'Of: Wie zich kleedt als iemand van aanzien wordt daarmee nog niet aanzienlijk.',
      2 => 'Of: Fraaie kleding en sieraden maken een lelijk mens niet mooi.'
    )
  ),
  2 => array(
    'category' => 'aap',
    'proverb' => 'Als apen hoger klimmen willen, ziet men gauw hun blote billen.',
    'explanation' => array(
      0 => 'Iemand die meer wil dan hij kan, maakt zich snel belachelijk.',
    )
  ),
);

这是我现在使用的代码:

if ($x = urlToXpath($url, true))
{
  $keywords = array();
  foreach ($x->query('/html/body/div[3]/div[3]/h2/span[@class="mw-headline"]') as $node)
  {
    $keywords[] = trim($node->nodeValue);
  }

  $data = array();
  foreach ($x->query('/html/body/div[3]/div[3]/dl/dd/dl') as $node)
  {
    $proverbs = array();
    foreach ($x->query('dd[@style="font-weight: bold"] | dd/b', $node) as $childNode)
    {
      $proverbs[] = trim($childNode->nodeValue);
    }
    $descriptions = array();
    foreach ($x->query('dd[position()>1]/small', $node) as $childNode)
    {
      $descriptions[] = trim(preg_replace('/^((Ook|Of):)/i', '', $childNode->nodeValue));
    }
    $data[] = array('proverbs' => $proverbs, 'descriptions' => $descriptions);
  }
}

2 个答案:

答案 0 :(得分:1)

要使用xpath执行此操作,您可能需要选择每个H2,然后使用this solution选择其间所有包含谚语的节点。然后在这些节点上执行相同的操作以查找说明。

您可能会发现下载页面的wikitext(例如like this)更容易,并使用简单的文本解析器处理文本中的行。如果不是这样,您至少应使用action=render来获取版本without all the skin-related HTML

答案 1 :(得分:0)

此XPath表达式为第一个谚语选择所需(三个)节点:

 /html/body/div[3]/div[3]/h2[1]/span[@class="mw-headline"]
|
 /html/body/div[3]/div[3]/h2[1]/following-sibling::dl[1]/dd/dl/dd[1]/b 
|  
 /html/body/div[3]/div[3]/h2[1]/following-sibling::dl[1]/dd/dl/dd[2]/small

第二个谚语所需的三个节点由此XPath表达式选择(请注意,只有索引从1增加到2):

 /html/body/div[3]/div[3]/h2[2]/span[@class="mw-headline"]
|
 /html/body/div[3]/div[3]/h2[2]/following-sibling::dl[1]/dd/dl/dd[1]/b 
|  
 /html/body/div[3]/div[3]/h2[2]/following-sibling::dl[1]/dd/dl/dd[2]/small

...等

这为您提供了一个很好的填充数组的算法 - 迭代索引:1,2,3,...直到某些索引K对构造的XPath表达式的评估不选择任何节点 - 然后你已经完成了。