【问题标题】:DOMXPath/PHP - Get a value only after specific occurrenceDOMXPath/PHP - 仅在特定发生后获取值
【发布时间】:2015-03-31 19:38:29
【问题描述】:

伙计们,我正在解析一个 URL 以获取 HTML dom 元素。

这是我的代码:

<?PHP
$url = 'http://www.sportsdirect.com/nike-satire-mens-skate-shoes-242188?colcode=24218822';

libxml_use_internal_errors(true);
$dom = new DOMDocument; 

$dom->loadHTMLFile($url); 

$xp = new DOMXPath($dom);
$qry = '//script[starts-with(normalize-space(.), "var colourVariantsInitialData")]';

$rawtxt = $xp->query($qry)->item(0)->nodeValue;


$jsonStart = strpos($rawtxt, '[');
$jsonEnd = strrpos($rawtxt, ']');

$collections = json_decode(substr($rawtxt, $jsonStart, $jsonEnd - $jsonStart + 1));

foreach ($collections[1]->SizeVariants as $item) {
    $SizeName = $item->SizeName;
    $PriceUnformated = $item->ProdSizePrices->SellPrice;

    $find = array('£');
    $replace   = array('');
    $Price = str_replace($find, $replace, $PriceUnformated);

    echo "SizeName: <b>$SizeName</b> - Price: <b>$Price</b><br>";

}

此代码正在从输出源的脚本中获取“文本”。 以下是此脚本的完整文本:http://pastebin.com/FwK9Z8CP

我的代码给出以下结果:

SizeName: 7 (41) - Price: 27.00
SizeName: 8 (42.5) - Price: 36.00
SizeName: 9 (44) - Price: 36.00
SizeName: 9.5 (44.5) - Price: 36.00
SizeName: 11 (46) - Price: 36.00

我的问题是:

如何仅获取特定 SizeName 的结果,例如 SizeName 7 (41)?

提前致谢!

【问题讨论】:

    标签: php xml json algorithm domxpath


    【解决方案1】:

    $specific 有您要查找的字符串。将代码中的 foreach 更改为:

    $specific = '7 (41)';
    
    foreach ($collections[1]->SizeVariants as $item) {
        $SizeName = $item->SizeName;
    
    if(trim($SizeName) == trim($specific)) {
    
        $PriceUnformated = $item->ProdSizePrices->SellPrice;
    
        $find = array('£');
        $replace   = array('');
        $Price = str_replace($find, $replace, $PriceUnformated);
    
        echo "SizeName: <b>$SizeName</b> - Price: <b>$Price</b><br>";
    }
    }
    

    【讨论】:

    • 感谢阿德里安的回答,我们可以使用preg_quote($specific),这样我们就可以跳过必须删除(等符号的部分?
    • @TonyStark 如果你只想要价格,现在检查答案,或者告诉我你期望的输出
    • 不不,这很酷!但是你能再看看我更新的评论吗?
    • 我们可以使用preg_quote 来转义特殊符号吗?
    • @TonyStark 但如果您使用 preg_quote 更难获得 ID,答案并不能解决您的问题?
    【解决方案2】:

    如何仅获取特定 SizeName 的结果,例如 SizeName 7 (41)?

    由于文本作为一个整体是 XML 文档的一部分,所以不能使用 XML 解析器。

    所以从技术上讲,这不是 xpath 问题。

    您已经将字符串解析为 JSON 并且您成功了。但是你还是不够自信。

    因此,您可以开发一个在 JSON 数据之上工作的数据模型,然后在其上实施过滤器。一个简单的模型可以使用 Interator 来遍历项目,并使用 FilterIterator 来仅选择具有特定属性值的项目。

    ...
    
    $xpath  = new DOMXPath($dom);
    $query  = '//script[starts-with(normalize-space(.), "var colourVariantsInitialData")]';
    $script = $xpath->query($query)->item(0)->nodeValue;
    
    $variants = SizeVariants::create($script); # Iterator
    $variants = new SizeFilter($variants); # FilterIterator
    
    foreach ($variants as $item) {
        $SizeName        = $item->SizeName;
        $PriceUnformated = $item->ProdSizePrices->SellPrice;
    
        $find    = array('£');
        $replace = array('');
        $Price   = str_replace($find, $replace, $PriceUnformated);
    
        echo "SizeName: **$SizeName** - Price: **$Price**\n";
    }
    

    示例输出(降价):

    尺寸名称:7 (41) - 价格:27.00

    还有the example code

    【讨论】:

      猜你喜欢
      • 2013-02-20
      • 1970-01-01
      • 2012-05-10
      • 1970-01-01
      • 1970-01-01
      • 2020-04-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多