2011-09-18 12 views
2

私はいくつかのHTMLのスクレープを行い、この1つのクエリで壁に当たっています。私は、次のHTMLページの構造からの値のセットを返すようにしようとしています:PHPのXPath部分文字列 - 最初の結果のみを返した後

<div id="product-grid"> 
    <ul> 
     <li><div class="price">Cash Price: $20.00</div></li> 
     <li><div class="price">Cash Price: $30.00</div></li> 
     <li><div class="price">Cash Price: $40.00</div></li> 
    </ul> 
</div> 

私はリストで返さ"$20.00"価格を取得しようとしています。次のXPathを使用する場合:

id('product-grid')//p[@class="price"] 

すべての「現金価格:$ 40.00」の結果リストが表示されます。次のクエリを試してみてください:

substring-after(id('product-grid')//p[@class="price"] , "Price: ") 

私は正しい出力を得ていますが、最初の結果しか得られません。誰も私はどのようにすべての結果を得ることができますか?

XPathの場合、PHP5.3.3libxml 2.7.8と実行しています。私はxpathを次のように呼んでいます:

$xpath = new DOMXPath($html); 
$resultset= $xpath->query($query); 

私はこれがなぜ起こっているのかを調べようと怒っています!助けてください!

答えて

1

申し訳ありませんが、これは1ステップで可能だとは思いません。私が知る限り、XPath 1.0はXPathパスの終わりに関数呼び出しをサポートしていません。答えはhereと同じです。

さらに、idがルート要素にあり、特別に選択する必要がないため、id('product-grid')を最初のパス部分として使用しないでください。あなたのサンプルXMLがより大きなXML文書の断片に過ぎない場合は、id()が必要かもしれません。

予想通り、次の作品は:

$xml = new DOMDocument(); 
$xml->loadXML('<div id="product-grid"> 
<ul> 
    <li><div class="price">Cash Price: $20.00</div></li> 
    <li><div class="price">Cash Price: $30.00</div></li> 
    <li><div class="price">Cash Price: $40.00</div></li> 
</ul> 
</div>'); 
$xpath = new DOMXPath($xml); 
foreach ($xpath->query('//div[@class="price"]') as $n) { 
    var_dump(substr($n->nodeValue, strpos($n->nodeValue, '$'))); 
} 
1

リストを取得した後に部分文字列を使用する必要があります。

id('product-grid')//div[@class="price"][substring-after(., 'Price: ')] 

これは機能するはずです。

編集:これは動作しているようです。しかし、私はsubstring'd値を取得する方法がわからないので、戻り値をテストすることはできません。あなたは何を使うのですか ?

+0

残念ながら、これはphp/xpath構文エラーをスローします。 – Michael

+0

エラー出力は何ですか? – Tom

+1

軸上の関数を使用するのはXPath 2.0の機能です。おそらく、標準のPHP環境では利用できません。 'id( 'product-grid')// p [@ class =" price "] [substring-after(。、 'Price:')]述語フィルタに適用できるはずです。また、サンプルXMLは 'div'要素を' @ class'と表示していますが、XPath(そしてあなたの答え)の例は 'p'が' @ class'を持つことを期待しています。 –

1

単一の文字列引数を期待しますが、ノードを与えられている定義により、任意の関数ので、指名手配処理は、1つだけのXPath 1.0式として指定することはできません-setは、このノード集合の(ドキュメント順の)最初のノードの文字列値をとります。

また、XPath 1.0のXPath 2.0とは異なり、関数呼び出しをロケーションステップとして指定することはできません。

count(id('product-grid')//p[@class="price"]) 
Nは別のXPath式を評価した結果である 1,2,..., N、各式で $kを置換、

substring-after((id('product-grid')//p[@class="price"])[$k], "Price: ") 

N回:

したがって、一つの解決策は、このXPath式を発行することです

XPath 2.0を使用すると、このシンプルで単一の表現でこれを行うことができます

id('product-grid')//p[@class="price"]/substring-after(., "Price: ") 

評価すると、正確に必要な文字列が生成されます。

関連する問題