2015-05-12 36 views
1

我想通过一系列HTML元素进行搜索并提取某些div(基于类名称)中的文本,但是我似乎无法搜索单个元素,只搜索所有节点。PHP&DOM:如何使用类名称搜索单个元素?

<html> 
<div class=parent> 
    <div videoid=1></div> 
    <div class=inner>Testing 
     <div class=title>Test</div> 
     <div class=date>Test</div> 
     <div class=time>Test</div> 
    </div> 
</div> 

<div class=parent> 
    <div videoid=2></div> 
    <div class=inner>Testing 
     <div class=title>Test</div> 
     <div class=date>Test</div> 
     <div class=time>Test</div> 
    </div> 
</div> 

<div class=parent> 
    <div videoid=3></div> 
    <div class=inner>Testing 
     <div class=title>Test</div> 
     <div class=date>Test</div> 
     <div class=time>Test</div> 
    </div> 
</div> 
</html> 
$url = new DOMDocument; 
$url->loadHTMLFile("text.html"); 

$finder = new DomXPath($url); 
$classname="parent"; 
$nodes = $finder->query("//*[contains(concat(' ', normalize-space(@class), ' '), ' $classname ')]"); 
$count = 0; 
foreach($nodes as $element) { //extracts each instance of the parent div into it's own element. 

//within the parent div extract the value for the videoid attribute within the following child div belonging to the following attribute: videoid; 

//within the parent div extract the text within the following child div belonging to the following class: title; 

//within the parent div extract the text within the following child div belonging to the following class: date; 

//within the parent div extract the text within the following child div belonging to the following class: time; 
} 

虽然只有一个每个每个父母中的子元素的情况下,他们可能是在父DIV任何顺序,并能与自己的孩子。基本上我正在寻找某种递归搜索,我认为?

+0

你就不能搜索'的div [@类=“父“]',你的标记似乎不符合。只需使用上下文节点获取 – Ghost

+0

下的其他子节点,这就是我所做的?这让我每个父节点,因为它是自己的元素(在每个循环内),但它不会让我以相同的方式搜索这些元素。我再次以错误的方式寻找?我应该不使用$ finder->查询吗? –

+0

是@John你可以搜索该循环下的重新生成的值(找到的父元素) – Ghost

回答

0

从你得到的parent(元素),你可以继续搜索你需要的值。 ->query(expression, context node)有第二个参数,您可以从需要搜索的位置放置上下文节点。

粗糙例如:

// for each found parent node 
foreach($parents as $parent) { 
    $id = $finder->query('./div[@class="id"]', $parent)->item(0)->nodeValue; 
    // create another query     ^using the found parent as your context node 
} 

所以在应用这些:

$finder = new DomXPath($url); 
$classname = "parent"; 
$parents = $finder->query("//div[@class='$classname']"); 
if($parents->length > 0) { 
    foreach($parents as $parent) { 
     $id = $finder->query('./div[@class="id"]', $parent)->item(0)->nodeValue; 
     $title = $id = $finder->query('./div[@class="inner"]/div[@class="title"]', $parent)->item(0)->nodeValue; 
     $date = $id = $finder->query('./div[@class="inner"]/div[@class="date"]', $parent)->item(0)->nodeValue; 
     $time = $id = $finder->query('./div[@class="inner"]/div[@class="time"]', $parent)->item(0)->nodeValue; 

     echo $id, '<br/>', $title, '<br/>', $date, '<br/>', $time, '<hr/>'; 
    } 
} 

Sample Output

这就是当你想到结构是这样的总是如此。您可以在父里面只是搜索与查询,并获得第一个发现,如果标记将是灵活的:

foreach($parents as $parent) { 
    $title = $finder->evaluate('string(.//*[@class="title"][1])', $parent); 
    echo $title, '<br/>'; 
} 

Sample Output

+0

我注意到你已经使用了item(0),现在很可能儿童元素将处于任何顺序之内,并且在任何数量的内部div中,不仅仅是直接在父母之下。我将如何解释这一点?我想我需要一个递归搜索来搜索所有父母的孩子和他们自己的孩子,直到找到与该类相匹配的元素为止。 –

+0

@JohnBergqvist yoiu'll需要相应地更改查询,编辑 – Ghost

+0

嗯,它现在不会返回任何东西:/有什么方法可以让我查看每个父元素的每个孩子及其子元素吗? incase我有结构错误或什么的? –