xpath: How to combine multiple conditions on different axes - xpath

I try to extract all links based on these three conditions:
Must be part of <div data-test="cond1">
Must have a <a href="..." class="cond2">
Must not have a <img src="..." class="cond3">
The result should be "/product/1234".
<div data-test="test1">
<div>
<div data-test="cond1">
Link 1
<div class="test4">
<div class="test5">
<div class="test6">
<div class="test7">
<div class="test8">
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div data-test="test2">
<div>
<div data-test="cond1">
Link 2
<div class="test4">
<div class="test5">
<div class="test6">
<div class="test7">
<div class="test8">
<img src="bild.jpg" class="cond3">
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
I'm able to extract the links with the following xpath query.
//div[starts-with(#data-test,"cond")]/a[starts-with(#class,"cond")]/#href
(I know the first part is not really neccessary. But better safe than sorry.)
But I'm still struggling with excluding the links containing an descendant img tag and how to add it to the query above.

This should do what you want:
//div[#data-test="cond1" and not(.//img[#class="cond3"])]
/a[#class="cond2"]
/#href
/product/1234

Related

XPath how to find nested element on first level [duplicate]

This question already has answers here:
Difference between "//" and "/" in XPath?
(4 answers)
Closed 4 months ago.
I have following XML:
<article>
<div class="class1">
<span>Article header 1</span>
<div>
<span>Date</span>
</div>
</div>
<div class="class2">
<span>Details</span>
<div class="class3">
<span>Number</span>
</div>
</div>
<div>
<span>Price 1</span>
</div>
<div class="class3">
<span>Footer 1</span>
<div>Footer details</div>
</div>
</article>
<article>
<div class="class1">
<span>Article header 2</span>
<div>
<span>Date</span>
</div>
</div>
<div>
<span>Price 2</span>
</div>
<div class="class2">
<span>Details</span>
<div class="class3">
<span>Number</span>
</div>
</div>
<div class="class3">
<span>Footer 2</span>
<div>Footer details</div>
</div>
</article
And I want to select only DIV without class and only from first nesting level
In this case
<div>
<span>Price 1</span>
</div>
and
<div>
<span>Price 2</span>
</div>
Note that this div in first article is on 3 place but in second article is on 2 place
I tried to use
//div[not(#class)]
but it find all elements in article, not only from first nest
You were close to the right expression.
This will select what you are looking for:
article/div[not(#class)]
This article/div indicates the direct div child element of the top node article.

Laravel Blade foreach combine

I have two separate divs, one where the images are loaded and the other where the data is displayed.
<div class="banner-slider-image">
<div class="swiper-container">
<div class="swiper-wrapper">
<!-- Slide Item -->
<div class="swiper-slide">
<div class="bg" style="background-image: url(include/assets/images/main-slider/1.jpg);">
</div>
</div>
</div>
</div>
</div>
<div class="banner-slider-content">
<div class="side-text">AVANT</div>
<div class="swiper-container banner-slider">
<div class="swiper-wrapper">
#if(count($listings) > 0)
#foreach($listings as $listing)
<!-- Slide Item -->
<div class="swiper-slide">
<div class="content-outer">
<div class="content-box">
<div class="inner">
<h5>{{$listing->first_name}} {{$listing->last_name}}</h5>
<h1><span>{{$listing->name}}</span> </h1>
<div class="text">{{$listing->property_description}}.</div>
<div class="link-box">View Listing</div>
</div>
</div>
</div>
</div>
#endforeach
#endif
</div>
</div>
</div>
So the first div will also be in a foreach loop, but I dont know how I can combine the two where they show the same related data.
Use 2 foreach loops . It is the easiest and desired solution for you. or you can define two variable and concat the contents using one forloop and then display them later like
#php
$first='';
$second='';
#endphp
#if(count($listings) > 0)
#foreach($listings as $listing)
#php
$first.='first div content';
$second.='second div content';
#endphp
#endforeach
#endif
<div class="banner-slider-image">
<div class="swiper-container">
<div class="swiper-wrapper">
{!!$first!!}
</div>
</div>
</div>
<div class="banner-slider-content">
<div class="side-text">AVANT</div>
<div class="swiper-container banner-slider">
<div class="swiper-wrapper">
{!!$second!!}
</div>
</div>
</div>
<html>
<body>
#section('sidebar')
This is the master sidebar.
#show
<div class="container">
#yield('content')
</div>
</body>
use for yield

How to get last child while parsing HTML with Goutte in Laravel

<div class="table">
<div class="table-head">
<div class="table-head-title">Ranking Equipos</div>
</div>
<div class="table-body">
<div class="table-body-row active">
<div class="col-key">Mark</div>
<div class="col-value">9233</div>
</div>
<div class="table-body-row">
<div class="col-key">Amanda</div>
<div class="col-value">7216</div>
</div>
<div class="table-body-row">
<div class="col-key">Mark</div>
<div class="col-value">6825</div>
</div>
<div class="table-body-row">
<div class="col-key">Paul</div>
<div class="col-value">6184</div>
</div>
<div class="table-body-row">
<div class="col-key">Amanda</div>
<div class="col-value">5866</div>
</div>
</div>
</div>
This is my HTML and I want to get last child of .table-body.
I tried to use JavaScript like logic and used indexing like this
$lastChild = $node->filter('.table-body .table-body-row')[4]; but it shows error. Cannot use object of type "Symfony\Component\DomCrawler\Crawler" as array
I was stuck in similar situation recently and I resolve this by using last() method. Syntax is here: $node->filter('.table-body .table-body-row')->last();

How to select text node without preceding text in XPath?

<div class="a">
<div class="a random number of div wrapers">
<div>Random1<em>Median</em>
<div class="b">
<div class="c">Edit</div>
</div>
</div>
<div>Random2<em>Median</em></div>
<div>
<em>Median</em>
</div>
<div>Random3<em>Median</em></div>
<div>Random4<em>Median</em>
<div>Random4<em>Median</em></div>
</div>
</div>
<div class="a">
<div class="a random number of div wrapers">
<div>Random1<em>Median</em></div>
<div>Random2<em>Median</em></div>
<div>
<em>Median</em>
</div>
<div>Random3<em>Median</em>
<div class="b">
<div class="c">Edit</div>
</div>
</div>
<div>Random4<em>Median</em>
</div>
</div>
In this case, how to get the two nodes contains 'Median' that doesn't have text before it using XPath?
I prefer not using the index because the node position could be random.
Maybe try:
//*[.='Median'][not(preceding-sibling::text()[normalize-space()])]

Xpath keeps selecting all objects of the given class instead of the first

This one has me stumped., I'm trying to select the first class = csb-quantity-listbox object of the below using the XPATH //select[#class='csb-quantity-listbox'][1], but instead of selecting the first quantity listbox it's selecting ALL the listboxes on the page with that class (see image below).
What am I doing wrong?
<div class="gwt-product-detail-products-container">
<div class="gwt-product-detail-products-header-column">
</div>
<div id="gwt-product-detail-widget-id-12766" class="gwt-product-detail-widget">
<div class="gwt-product-detail-widget-image-column ui-draggable" title="12766">
<div class="gwt-product-detail-widget-options-column">
</div>
<div class="gwt-product-detail-widget-price-column">
</div>
<div class="gwt-product-detail-widget-quantity-panel">
<select class="csb-quantity-listbox" name="quantity_12766"></select>
</div>
<div class="gwt-bundle-add-to-cart-btn">
</div>
</div>
</div>
<div id="gwt-product-detail-widget-id-10617" class="gwt-product-detail-widget">
<div class="gwt-product-detail-widget-image-column ui-draggable" title="10617">
<div class="gwt-product-detail-widget-options-column">
</div>
<div class="gwt-product-detail-widget-price-column">
</div>
<div class="gwt-product-detail-widget-quantity-panel">
<select class="csb-quantity-listbox" name="quantity_10617"></select>
</div>
<div class="gwt-bundle-add-to-cart-btn">
</div>
</div>
</div>
</div>
Image:
You just need to put brackets around the statement before the [1]
Like so:
(//select[#class='csb-quantity-listbox'])[1]

Resources