3

解析する一連の html アイテムがあります。クラス名が「uid-g-uid」で終わる div の内容を解析する必要があります。以下はサンプルdivです...

<div class="uid-g-uid">1121</div>

<div class="yskisghuid-g-uid">14234</div>

<div class="kif893jduid-g-uid">114235</div>

以下の組み合わせを試しましたが、うまくいきませんでした

$doc = new DOMDocument();
$bdy = 'HTML Content goes here...';
@$doc->loadHTML($bdy);
$xpath = new DomXpath($doc);
$div = $xpath->query('//*[@class=ends-with(., "uid-g-uid")]');

そしてまた試した

$doc = new DOMDocument();
$bdy = 'HTML Content goes here...';
@$doc->loadHTML($bdy);
$xpath = new DomXpath($doc);
$div = $xpath->query('//*[@class="*uid-g-uid"]');

助けてください!

4

4 に答える 4

3

end-with() は Xpath 2.0 を必要とするため、Xpath 1.0 である DOMXPath では機能しません。ただし、このようなものは機能するはずです:

$xpath->query('//*["uid-g-uid" = substring(@class, string-length(@class) - 8)]');
于 2013-04-09T12:29:31.830 に答える
2

XPath 1.0 では使用できない XPath 関数を探しているので、 PHP が提供するDOMXPath::registerPhpFunctions機能を使用して、XPath クエリの任意の PHP 関数を呼び出すことができると思います。preg_matchこれにより、次のように関数を呼び出すこともできます。

$html = <<< EOF
<div class="uid-g-uid">1121</div>
<div class="yskisghuid-g-uid">14234</div>
<div class="kif893jduid-g-uid">114235</div>
EOF;
$doc = new DOMDocument();
libxml_use_internal_errors(true);
$doc->loadHTML($html); // loads your html
$xpath = new DOMXPath($doc);

// Register the php: namespace (required)
$xpath->registerNamespace("php", "http://php.net/xpath");

// Register PHP preg_match function
$xpath->registerPHPFunctions('preg_match');

// call PHP preg_match function on your xpath to make sure class ends
// with the string "uid-g-uid" using regex "/uid-g-uid$/"
$nlist = $xpath->evaluate('//div[php:functionString("preg_match",
                           "/uid-g-uid$/", @class) = 1]/text()');

$numnodes = $nlist->length; // no of divs matched
for($i=0; $i < $numnodes; $i++) { // run the loop on matched divs
   $node = $nlist->item($i);
   echo "val: " . $node->nodeValue . "\n";
}
于 2013-04-09T12:54:18.910 に答える
2

特定の文字列で終わる文字列をチェックする XPath 1.0 クエリを実行したいと考えています。このends-with()バージョンでは文字列関数は使用できません。

これを行う方法は複数あります。あなたの場合のように、部分文字列は常に一度だけそこにあり、最後に使用できますcontains()

//*[contains(@class, "uid-g-uid")]

部分文字列が他の場所にもある可能性があり、それが気に入らない場合は、それが最後にあるかどうかを確認します。

//*[contains(@class, "uid-g-uid") and substring-after(@class, "uid-g-uid") = ""]

そこに複数回存在する可能性がある場合、これも機能しません。その場合、文字列がそれで終わっているかどうかを確認できます:

//@class[substring(., string-length(.) - 8, 9) = "uid-g-uid"]/..

これはおそらく最も単純なバリアントです。または、 の 3 番目の引数substring()はオプションであり、最後まで比較できます。

//@class[substring(., string-length(.) - 8) = "uid-g-uid"]/..
于 2013-04-09T12:49:28.680 に答える