簡體   English   中英

DOMXPATH->未獲取div的第一個元素

[英]DOMXPATH-> not getting first elements of div

我正在使用DOMXPath來獲取特定節點的內容。 對於我的問題,我想獲取除嵌套div之外的所有匹配div的文本。

$html = 
'<div itemscope="itemscope" itemtype="http://schema.org/Event">
  <span itemprop="name"> Miami Heat at Philadelphia 76ers - Game 3 (Home Game 1)</span>
  <meta itemprop="startDate" content="2016-04-21">
    Thu, 04/21/16
    8:00 p.m    
  <div itemprop="offers" itemscope="itemscope" itemtype="http://schema.org/AggregateOffer">
    Priced from: <span itemprop="lowPrice">$35</span>
    <span itemprop="offerCount">1938</span> tickets left
  </div>
  <meta itemprop="endDate" content="2020-3-2"> end date of year    
  <div itemprop="attendee" itemscope="itemscope" itemtype="http://schema.org/Person">
     <span itemprop="name">Jane Doe</span>
     <meta itemprop="birthDate" content="1975-05-06"> 
    <div itemprop="sibling" itemscope="itemscope" itemtype="http://schema.org/Person">
        <span itemprop="name">Fatima Zohra</span>
        <meta itemprop="birthDate" content="1991-6-5">Jan 6
     </div>      
  </div>
</div>';

我首先嘗試了以下方法,但這沒有返回嵌套的div:

$tags = $xpath->query("//div[@itemscope='itemscope'][not(self::div)]/text()");

我目前的嘗試如下,但不起作用:

$dom = new DOMDocument;
$dom->loadHTML($html);
$xpath = new DOMXPath($dom);
$tags = $xpath->query('//div[not(ancestor::div)]');

foreach ($tags as $node) {
    echo $node->nodeValue; // body

}

最好將這個問題分為兩個部分:

  1. 返回匹配的div列表
  2. 打印每個div的所有內容,除包含div的內容外

下面演示了這種方法:

$dom = new DOMDocument;
$dom->loadHTML($html);
$xpath = new DOMXPath($dom);
$divs = $xpath->query("//div[@itemscope='itemscope']");

foreach ($divs as $div) {
        $nodelist = $xpath->query('child::node()[not(self::div)][normalize-space()]',$div);

        foreach ($nodelist as $node) {
                echo $node->nodeValue . "\n";
        }
        echo "\n---------------------\n";
}

請注意以下幾點:

  • 'child :: node()'而不是'*'包括文本節點
  • '[normalize-space()]刪除多余的空格,包括換行符

順便說一句,“ not(ancestor :: div)”明確表示不返回嵌套在其他div中的div。

您要查找的微數據具有itempropitemscopeitemtypecontent屬性。

因此,您的問題實際上是關於如何從HMTL文檔中獲取微數據的問題。 這基本上是XML解析的問題。 由於schema.org微數據是(或多或少直接的),我強烈建議使用DOMDocument加載HMTL文檔,而使用SimpleXML解析數據。

基於libxml的PHP XML擴展中的解析僅靠xpath不能直接進行,因為該庫僅支持xpath 1.0,並且您無法使用該xpath版本做任何事情。 特別是在這種情況下,只選擇后代或自身特定的相對不再次包含與特定屬性的孩子contextnode一個屬性有。 因此,這總是需要一些包裝代碼。 如果您有興趣閱讀有關此內容的更多信息,我發現以下問題圍繞着與您的xpath問題類似的問題:

因此,將xpath代碼包裝在某個類中,並立即訪問感興趣的數據:

$dom = new DOMDocument;
$dom->loadHTML($html);

$micro = new Micro($dom);
$event = $micro->Event;

foreach($event as $name => $value) {
    if ($value->isEmbed()) continue;
    printf("%s => %s\n", $name, $value);
}

提供以下輸出:

name =>  Miami Heat at Philadelphia 76ers - Game 3 (Home Game 1)
startDate => 2016-04-21
endDate => 2020-3-2

或者您只需訪問:

$micro->Event->name; # Miami Heat at Philadelphia 76ers - Game 3 (Home Game 1)

Micro Microdata類為要點

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM