简体   繁体   中英

DOMXPath/PHP - Get a value only after specific occurrence

Guys I'm parsing an URL to get HTML dom elements.

Here is my code:

<?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>";

}

This code is fetching "text" from a script from the output source. Here is the complete text from this script: http://pastebin.com/FwK9Z8CP

My code is giving the following result:

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

My question is:

How I can get only the result for a specific SizeName, for example let's say for SizeName 7 (41) ?

Thanks in advance!

$specific have the string that you want find. Change the foreach in your code to this:

$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>";
}
}

How I can get only the result for a specific SizeName, for example let's say for SizeName 7 (41) ?

As the text as a whole is part of the XML document, you can't with the XML parser.

So technically this is not an xpath question.

You already parse the string as JSON and you're successful with that. But you still are not confident enought.

You can therefore develop a data-model that works on top of the JSON data and then implement a filter on it. A simple model could be done with an Interator to traverse the items and the a FilterIterator to pick only those with specific property values.

...

$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";
}

Exemplary output (markdown):

SizeName: 7 (41) - Price: 27.00

And the example code .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM