Getting next element - c#

I need to get a next (sibling) element of the one with "Yes" as its text. I can use the text "Yes", css and part of the id, but the number (e.g.. 106) is unfortunately excluded. Also I can't directly get that sibling, because of that exclusion. Here is a part of the HTML code:
<a style="right: auto;" class="x-btn x-box-item x-toolbar-item" id="button-106">
<span id="button-106-btnWrap" role="presentation" class="x-btn-wrap" unselectable="on">
<span id="button-106-btnEl" class="x-btn-button" role="presentation">
<span id="button-106-btnInnerEl" class="x-btn-inner x-btn-inner-center">Yes
</span>
<span role="presentation" id="button-106-btnIconEl" class="x-btn-icon-el">
</span>
</span>
</span>
</a>
I came up with this query, but it doesn't seem to work:
By.XPath(".//*[text() = 'Yes' and contains(id(), '-btnInnerEl')/following-sibling::*]")
How can I alter this query so I can get the next element?

To select the span with id button-106-btnIconEl:
//span[contains(#id,'-btnInnerEl')][normalize-space(text())='Yes']/following-sibling::span

Related

Selecting a parent of a child element using XPath

Before I start in the source code I have included in this post I have replaced any sensitive data with a string of "x".
<div class="pod productPod icon-life clearFix nonwrap"
id="xxxxxxxxxx"
internalid="xxxxxxxxxx"
data-properties-type="xxxxxxxxxx"
data-properties-code="xxxxxxxxxx"
data-properties-loaded="False"
data-properties-url="xxxxxxxxxx"
data-properties-showmaintenanceerrormessage="False"
data-properties-product-type="xxxxxxxxxx">
<span class="podTitle">Your policies</span>
<div id="1" class="productPodInner" data-qa-productpod="">
<span class="notificationBubble fullProdLarge" aria-hidden="true"></span>
<h2><a data-feedback="" class="clearFix roundelLink" href="#productId0" data-roundel-id="0">
<span class="productIconWrapper">
<span class="productIcon">
</span>
</span>
<span class="productData">
<span class="productName" style="min-height: auto;">Protection</span>
<span class="notificationBubble fullProd"></span>
</span>
</a></h2>
<div class="productDetails podContent" id="#productId0" style="width: 1903px; left: -306.703px;">
<div class="productDetailsInner clearFix">
<h3>xxxxxxxxxx</h3>
<!-- TODO:: Display this in the 2nd column-->
<dl class="initialPolicyContainer detailsList" style="display: none;">
<dt>Policy Number</dt>
<dd class="initialPolicyNumber" data-qa-text="xxxxxxxxxx">xxxxxxxxxx</dd>
</dl>
<div class="clearFix variant3Container" style=""><div class="group-1-2 clearFix">
<div class="column">
<dl class="detailsList">
<dt>Policy number</dt>
<dd class="policyNumberVal">xxxxxxxxxx</dd>
<dt>Term</dt>
<dd>xxxxxxxxxx</dd>
</dl>
So my goal here is to be able to select the top parent using an Xpath locator and then click on that with selenium.
On the website there is a pod with multiple roundel sections each containing its own policy. Normally I can select a roundel using an Xpath query that finds the roundel by the policyType(text) but if there are 2 policies with the same policyType then this Xpath locator will only find the first one.
Roundel has a unique policyNumberVal (line 29)
<dd class="policyNumberVal">xxxxxxxxxx</dd>
That I can locate using this Xpath:
//dd[#class='policyNumberVal' and text() = '{policyNumber}']
What I could like to know is, once I have located the 'policyNumberVal' how do I then step up and select the parent ?
Please let me know if you need any more information than this.
You can use the parent axis,
//dd[#class='policyNumberVal' and text() = '{policyNumber}']/parent::*
its abbreviation,
//dd[#class='policyNumberVal' and text() = '{policyNumber}']/..
or, elevate the predicate and select the parent directly:
//dl[dd[#class='policyNumberVal' and text() = '{policyNumber}']]

XPath for an element with same class names

Can anyone help me to derive the xpath (from second div the span element label which is GP)
<div class="ohg-patient-banner-suppl-info-section ohg-patient-banner-suppl-info-custom pure-u-1-5">
<div class="ohg-patient-banner-suppl-info-component-container ohg-patient-banner-suppl-info-component-left-bordered ohg-patient-banner-suppl-info-custom" aria-label="Visit Info" role="group"><div class="ohg-patient-banner-suppl-info-section-summary" aria-hidden="false">
</div>
<div class="ohg-patient-banner-suppl-info-section-detail" aria-label="" aria-hidden="true">
<div class="ohg-patient-banner-suppl-info-custom-field">
<span class=" " aria-hidden="true"></span>
<span class=" ohp-metadata-label">Location</span>
<span class="ohg-patient-banner-suppl-info-custom-row-value-icon " aria-hidden="true"></span>
<span class=" ohg-patient-banner-suppl-info-value">Tauranga Hospital - Assmt Plan Unit TAU - </span>
</div>
</div>
</div>
</div>
<div class="ohg-patient-banner-suppl-info-section ohg-patient-banner-suppl-info-custom pure-u-1-5">
<div class="ohg-patient-banner-suppl-info-component-container ohg-patient-banner-suppl-info-component-left-bordered ohg-patient-banner-suppl-info-custom" aria-label="GP Info" role="group"><div class="ohg-patient-banner-suppl-info-section-summary" aria-hidden="false">
</div>
<div class="ohg-patient-banner-suppl-info-section-detail" aria-label="" aria-hidden="true">
<div class="ohg-patient-banner-suppl-info-custom-field">
<span class=" " aria-hidden="true"></span>
<span class=" ohp-metadata-label">GP</span>
<span class="ohg-patient-banner-suppl-info-custom-row-value-icon " aria-hidden="true"></span>
<span class=" ohg-patient-banner-suppl-info-value">-</span>
</div>
</div>
</div>
</div>
My XPath which i wrote it work for the first div and it return the value Location :
.//*[#class='ohg-patient-banner-suppl-info-section-detail']/div[#class='ohg-patient-banner-suppl-info-custom-field']/span[#class=' ohp-metadata-label']
Xpath:
//*[#class='ohg-patient-banner-suppl-info-custom-field']//span[2]
then you can use gettext() to get GP as a text
Try this XPath-1.0 expression:
//*[#class='ohg-patient-banner-suppl-info-section-detail']/div[#class='ohg-patient-banner-suppl-info-custom-field' and span[#class=' ohg-patient-banner-suppl-info-value']='-']/span[#class=' ohp-metadata-label']
Its result is:
GP
programmatic solution:
your xpath actually does return both elements:
in your selenium lib you receive most likely an array and can select the second element of it
select the second element:
if its always the second element adding a [2] to the xpath helps
e.g. "(.//*[#class='ohg-patient-banner-suppl-info-section-detail'])[2]/div[#class='ohg-patient-banner-suppl-info-custom-field']/span[#class=' ohp-metadata-label']"
by a fixed text
If you have some text in the page that is fixed, e.g. Location you can use that as reference and then using ancestor and sibling axes
".//span[.='Location']//ancestor::div[#class='ohg-patient-banner-suppl-info-section-detail']//following-sibling::div[#class='ohg-patient-banner-suppl-info-section-detail']//span[#class=' ohp-metadata-label']"
Since you don't have other unique identifiers, and the class name is used by 2 spans, this is how you can identify that span based on its index, and is the shortest way:
xpath: (//span[#class=' ohp-metadata-label'])[2]
Now you can scrape the text by using selenium getText() method.
Note that we used index 2 to identify your locator, but if html code will change, and new similar spans will be added before this one, you will need to change the index.

access href value inside a div tag in c#

I have some divs like this:
<div class="compTitle options-toggle">
<h3 class="title">
<a class=" ac-algo fz-l ac-21th lh-24" href="http://www.bestbuy.com/">
Products - Best Buy
</a>
</h3>
</div>
I'm trying to get the href values inside the "compTitle options-togglet" div.how should I get "http://www.bestbuy.com/"?
i use this code for getting title
string titles = node.SelectSingleNode(".//h3[contains(#class,'title')]").InnerText;

Why does my 2nd tab automatically assign a tabIndex of -1

<li class="ui-state-default ui-corner-top ui-tabs-active ui-state-active" role="tab" tabindex="0" aria-controls="Tab0" aria-labelledby="ui-id-1" aria-selected="true">
<a href="#Tab0" class="ui-tabs-anchor" role="presentation" tabindex="-1" id="ui-id-1">
<span class="titlecase">jones,mike dr</span>
</a>
</li>
<li class="ui-state-default ui-corner-top" role="tab" tabindex="-1" aria-controls="Tab1" aria-labelledby="ui-id-2" aria-selected="false">
<a href="#Tab1" class="ui-tabs-anchor" role="presentation" tabindex="-1" id="ui-id-2">
<span class="titlecase">asdf,asdfasd mrs</span>
</a>
</li>
I have a function that will change the tab on the index its on, but for some reason it automatically gets -1 for the second so my onclick="javascript:ChangeTabLocation('1');" never hits the second tab.
Any ideas where in the code it automatically assigns a -1 to that?

get text inside a html element

I'm using HTMLAgilityPack to get text inside a list of certain nodes.
Basically I'm reading out a HTML page with the following HTML:
<div class="video-overview yt-grid-fluid">
<h3 class="video-title-container">
<span class="yt-badge-std">
WATCHED
</span>
<a href="/watch?v=S5FCdx7Dn0o&list=FLArRQZAMoAgECBIOn08gNeA&index=1" title="Bob Marley - Buffalo soldier" class="yt-uix-tile-link yt-uix-sessionlink" data-sessionlink="ei=c9tWUb3eJaOzhgG6kYHYAg&feature=plpp_video">
<span class="title video-title" dir="ltr">Bob Marley - Buffalo soldier</span>
</a>
</h3>
<p class="video-details">
<span class="video-owner">
by <span class="yt-user-name " dir="ltr">Pgroenberg</span>
</span>
<span class="video-view-count">
44,342,136 views
</span>
</p>
</div>
I want to get the text "Bob Marley - Buffalo soldier", which is inside <span class="title video-title" dir">.
I cant seem to find the right pattern:
string expression = #"//span[#class='title video-title' and #dir='ltr']/text()";
HtmlNodeCollection hnc = htmlDoc.DocumentNode.SelectNodes(expression);
hnc will be null because no nodes have matched with the expression. Why wont my expression work?

Categories