XPath: Get next after following sibling - html

In the following HTML code I need to extract class="list-item-child-label ng-inserted" but only in that part where I have class="fat-checkbox-checked"
<fat-option class="fat-option>
<fat-pseudo-checkbox class="fat-pseudo-checkbox ></fat-pseudo-checkbox>
<span class="fat-option-text">
<div class="justify-content">
<div class="align-items">
<fat-checkbox class="fat-checkbox-checked">
</fat-checkbox>
<div></div>
<div class="list-item-child-label"> TEXT AAA </div>
</div>
<div class="list-item-child-label ng-inserted"> TEXT BBB </div>
</div>
</span>
</fat-option>
<fat-option class="fat-option>
<fat-pseudo-checkbox class="fat-pseudo-checkbox ></fat-pseudo-checkbox>
<span class="fat-option-text">
<div class="justify-content">
<div class="align-items">
<fat-checkbox class="fat-checkbox">
</fat-checkbox>
<div></div>
<div class="list-item-child-label"> TEXT AAA </div>
</div>
<div class="list-item-child-label ng-inserted"> TEXT BBB </div>
</div>
</span>
</fat-option>
These xpaths that I tried to build:
'//div[contains(#class, "list-item-child-label ng-inserted")]/ancestor::span//div//fat-checkbox[contains(#class, "mat-checkbox-checked")]'
'//span//div//fat-checkbox[contains(#class, "fat-checkbox-checked")]/following-sibling::div[2]'
'//span//div//fat-checkbox[contains(#class, "fat-checkbox-checked")]/following-sibling::div[contains(#class, "list-item-child-label ng-inserted")]'
getting me only class="list-item-child-label"
Anyone knows how to build correct xpath to get class="list-item-child-label ng-inserted" with class="fat-checkbox-checked" without using contains(#text)?

Try below XPath to select required node
//div[fat-checkbox[#class="fat-checkbox-checked"]]/following-sibling::div[#class="list-item-child-label ng-inserted"]

To locate the element <div class="list-item-child-label ng-inserted"> followed by the element <fat-checkbox class="fat-checkbox-checked"> you can use either of the following xpath:
//fat-checkbox[#class='fat-checkbox-checked']//following::div[#class='list-item-child-label ng-inserted']

Related

Hide main div in which sub div contains specific text

I'm trying to make my first Tampermoney script
Here's an example of an html page :
<div class="a">
<div class="b">
"Hello world"
</div>
<div class="n">
"Test"
</div>
</div>
<div class="a">
<div class="d">
<div class="e">
...
<div class="n">
"Hello world"
</div>
</div>
</div>
</div>
I found this topic, very interesting, but I'm not able to make it fits my requirements : Hiding div that contains specific string
I would like to hide the divs class="a" ONLY if it contains a div class="n" that contains the text "Hello world".
Do I need to loop on all the divs class="a", to seek for a class="n" containing "Hello world" ? I'll need some help please...
<div class="a">
<div class="b">
"Hello world"
</div>
<div class="n">
"Test"
</div>
</div>
Hmmmm, I think it needs a few ajustements...
Here's my code :
$(window).load(function(){
$('._5g-l:contains("Publication suggérée")').closest('._5jmm _5pat _3lb4 m_95yeui-j _x72').hide();
});
The web page :
And the associated code :
<div data-fte="1" data-ftr="1" class="_5jmm _5pat _3lb4 m_95yeui-j _x72" id="hyperfeed_story_id_581d0a6f0b12a3832990101" data-testid="fbfeed_story" [...]>
<div class="_4-u2 mbm _5v3q _4-u8" id="u_jsonp_2_1f">
<div class="_3ccb _4-u8" [...]>
<div></div>
<div class="userContentWrapper _5pcr" role="article" aria-label="Actualité">
<div class="_1dwg _1w_m">
<div class="_5g-l"><span>Publication suggérée</span></div>
[...]
Also, I can't put in the webpage :
<script src="https://code.jquery.com/jquery-3.1.0.min.js"></script>
When I try to execute the commande in the console :
$('._5g-l:contains("Publication suggérée")').closest('._5jmm _5pat _3lb4 m_95yeui-j _x72').hide();
(unknown) Uncaught Error: <![EX[["Tried to get element with id of \"%s\" but it is not present on the page.","._5g-l:contains(\"Publication suggérée\")"]]]>
at h (https://www.facebook.com/rsrc.php/v3/yZ/r/AveNRnydIl_.js:36:166)
at i (https://www.facebook.com/rsrc.php/v3/yZ/r/AveNRnydIl_.js:36:293)
at <anonymous>:1:1
I think this will help you. And you want if class .a contain .n with text("hello world") , .a need to be hide. I just make edit your HTML part and also comment out which div will be hide. According to your HTML first one will be not hide because .n contain "test".
if any question or if you found anything wrong on my answer ask me. :) Live On Fiddle
UPDATE: In your Code the problem in your parent div you have 5 class _5jmm, _5pat, _3lb4, m_95yeui-j, _x72 but you write in jQuery closest('.5jmm _5pat _3lb4 m_95yeui-j _x72').hide(). So you can set only one class which is closest. And you don't
$(window).on('load', function() {
$('._5g-l:contains("Publication suggérée")').closest('._5jmm').hide();
});
<script src="https://code.jquery.com/jquery-3.1.0.min.js"></script>
<div data-fte="1" data-ftr="1" class="_5jmm _5pat _3lb4 m_95yeui-j _x72" id="hyperfeed_story_id_581d0a6f0b12a3832990101" data-testid="fbfeed_story" [...]>
<div class="_4-u2 mbm _5v3q _4-u8" id="u_jsonp_2_1f">
<div class="_3ccb _4-u8" [...]>
<div></div>
<div class="userContentWrapper _5pcr" role="article" aria-label="Actualité">
<div class="_1dwg _1w_m">
<div class="_5g-l"><span>Publication suggérée</span></div>
</div>
</div>
</div>
</div>
</div>

XPath to select link containing text?

I tried to use this XPath:
//*[contains(normalize-space(text()),'Jira')]
Also tried:
//*[contains(text(),'Jira')]
In the below HTML example, there is space before and after text "Jira". I am not able to click on the link:
<a href="#/crm/usergroup-edit?id=572a3c84e4b07f6189958700"
ng-repeat="gp in groups | filter : userGroupSearch | orderBy:'-name':1"
class="ng-scope">
<div class="inventoryPanel" ng-style="myStyle" style="width: 15.8%;">
<h4 class="ng-binding">
<div class="groupIcon G">
<div class="text ng-binding">P</div>
</div>Jira
</h4>
</div>
</a>
The following XPath will select all a elements whose string value contains a Jira substring:
//a[contains(.,'Jira')]

How to find the text in all div elements without the first div coming from class "B"

I'm trying to capture the text inside all the div elements without the text of the first div that is the child of class "B"
I've been banging my head all day, but I can't seem to get it to work properly.
<div class="A">
Text 1
</div>
<div class="B">
<div>
Welcome 1
</div>
<div>
Welcome 2
</div>
</div>
This is the expression I'm using:
//body//text()[not (//div[#class='B']/div[1])]
but it is not returning any results.
After making the XML well-formed by giving it a single root element,
<div>
<div class="A">
Text 1
</div>
<div class="B">
<div>
Welcome 1
</div>
<div>
Welcome 2
</div>
</div>
</div>
Here are all the div elements that have no div descendents and are not the first div with a parent with a #class attribute value of `B':
//div[not(descendant::div) and not(../#class='B' and position() = 1)]
The above XPath selects these two div elements:
<div class="A">
Text 1
</div>
<div>
Welcome 2
</div>
So you can get the associated text() nodes using this XPath:
//div[not(descendant::div) and not(../#class='B' and position() = 1)]/text()
...which will select:
Text 1
Welcome 2
without selecting Welcome 1, as requested.

HTML element to contain id or name from ko.observable using foreach

Below I have a for-each loop using knockout.js.
<div data-bind="foreach:Stuff">
<div class="row">
<span data-bind="text: $data.name"></span>
</div>
</div>
I need to have the HTML Element with an id or name or something that reflects a unique value related to the $data.name value, as another method runs asynchronously, and needs to know which HTML element to update.
Ideally, it would look something like this, I guess:
<div data-bind="foreach:Stuff">
<div class="row">
<span id="data-bind='text: $data.name'" data-bind="text: $data.name"></span>
</div>
</div>
I have found a knockout syntax that applies values during runtime to specified attributes:
<div data-bind="foreach:Stuff">
<div class="row">
<span data-bind="attr: { id: $data.name}"></span>
</div>
</div>
Are you looking for this
<div data-bind="foreach:Stuff">
<div class="row">
<span data-bind="text: $data.name,attr:{id:$data.name}'"></span>
</div>
</div>
Here name is a observable i believe when ever there is change in name in stuff it will automatically updates its value & attr:{id}just to give a dynamic id to element using available bindings .

Render HTML Page

This is my html page.
<body>
<div id="form1">
<root xmlns:NS='www.yembi.com'>
<NS:ENTRY Action='Users'>
<div class="colm1">
<NS:DISPLAY datafield="FirstName"></NS:DISPLAY>
</div>
<div class="colm2">
<NS:Text datafield='FirstName'/>
</div>
<div class="colm1">
<NS:DISPLAY datafield="MiddleName"></NS:DISPLAY>
</div>
<div class="colm2">
<NS:Text datafield='MiddleName'/>
</div>
<div class="colm1">
<NS:DISPLAY datafield="LastName"></NS:DISPLAY>
</div>
<div class="colm2">
<NS:Text datafield='LastName'/>
</div>
<div class="colm1">
<NS:DISPLAY datafield="Phone"></NS:DISPLAY>
</div>
<div class="colm2">
<NS:Text datafield='Phone'/>
</div>
<div class="colm3">
<NS:BUTTON ></NS:BUTTON>
</div>
</NS:ENTRY>
</root>
</div>
I wanna get this html into a temp variable. so tried like below
var Text = $("#form1").html();
I am getting full html content, But with small exceptions.
It not displaying the double quotes in div attributes.
I am getting the below output:
<ROOT xmlns:NS='www.yembi.com'>
<NS:ENTRY Action='Users'>
<DIV class=colm1>
<NS:DISPLAY datafield="FirstName"></NS:DISPLAY>
</DIV>
<DIV class=colm2> // Here it automatically removes the double quotes. how to retain this double quotes ?
<NS:Text datafield='FirstName'/>
</DIV>
<DIV class=colm1>
<NS:DISPLAY datafield="MiddleName"></NS:DISPLAY>
</DIV>
<DIV class=colm2>
<NS:Text datafield='MiddleName'/>
</div>
<DIV class=colm1>
<NS:DISPLAY datafield="LastName"></NS:DISPLAY>
</DIV>
<DIV class=colm2>
<NS:Text datafield='LastName'/>
</DIV>
<DIVclass=colm1>
<NS:DISPLAY datafield="Phone"></NS:DISPLAY>
</DIV>
<DIV class=colm2>
<NS:Text datafield='Phone'/>
</DIV>
<DIV class=colm3>
<NS:BUTTON ></NS:BUTTON>
</DIV>
</NS:ENTRY>
</ROOT>
As mentioned above it automatically remove the double quotes in DIV. How to retain this double quotes??
I suspect you are using jQuery or an equivalent:
See here from the documentation:
"This method uses the browser's innerHTML property. Some browsers may not return HTML that exactly replicates the HTML source in an original document. For example, Internet Explorer sometimes leaves off the quotes around attribute values if they contain only alphanumeric characters."
http://api.jquery.com/html/
So this is really browser dependent. You could use a javascript regex to make sure the quotes are where you need them to be:
Regex to put quotes for html attributes