0

特定のノードのコンテンツを取得するために 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

}
4

2 に答える 2

1

この問題は、次の 2 つの部分に分割するのが最適です。

  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 を返さないことを明確に示しています。

于 2013-03-18T11:37:54.410 に答える
0

探しているmicrodataは、、、およびitemprop属性itemscopeです。itemtypecontent

したがって、あなたの質問は実際には、その HMTL ドキュメントから microdata を取得する方法に関するものです。これは基本的に XML 解析の問題です。schema.org の microdata は (多かれ少なかれ単純です) ので、DOMDocument を使用して HMTL ドキュメントをロードし、SimpleXML を使用してデータを解析することを強くお勧めします。

ライブラリは xpath 1.0 のみをサポートし、その xpath バージョンではすべてを実行できないため、libxml ベースの PHP XML 拡張機能の解析は、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)

gist としてのMicroMicrodata クラス

于 2013-03-20T01:50:42.107 に答える