How to get parent element and then next element by - html

I want to get the parent of specify element (span with class is mw-headline) and then get the first next element of this parent.
<h2>
<span class="mw-headline" id="Botany">Botany
</span>
<span class="mw-editsection">
<span class="mw-editsection-bracket">
</span>edit<span class="mw-editsection-bracket">
</span>
</span>
</h2>
<ul>
<li><i>Malus</i>, the genus of all apples and crabapples</li>
<li>Cashew apple, the fruit that grows with the cashew nut</li>
<li>Custard apple, several fruits</li>
<li>Love apple:
<ul>
<li>Tomato</li>
<li><i>Syzygium samarangense</i>, a plant species in the Myrtaceae family</li>
</ul>
</li>
<li>Mammee apple (disambiguation)</li>
<li>May apple (<i>Podophyllum peltatum</i>)</li>
<li>Oak apple, a type of gall that grows on oak trees</li>
<li>Rose apple (disambiguation), several fruits</li>
<li>Thorn apple (disambiguation):
<ul>
<li><i>Crataegus</i> species</li>
<li><i>Datura</i> species</li>
</ul>
</li>
<li>Wax apple (<i>Syzygium samarangense</i>)</li>
<li>Hedge apple (<i>Maclura pomifera</i>)</li>
</ul>
I want to get first ul after h2 tag has specify span with class is mv-headline.
From xpath, i have very simple soltuion:
$x('//span[#class="mw-headline"]/following::ul[1]')
But I don't know how select it in selector with get parent (.. in xpath) and next element (following::node in xpath) in my case.
Please give me a solution by CSS selector.
Thanks & Best Regards,
Phuong Hoang

You do one mistake in your XPath, xpath should be:
$x('//h2[//span[#class="mw-headline"]]/following::ul[1]')

Related

Embedded and Internal CSS not affecting my lists

I am trying to get it so that my ingredients list is green, my equipment is red and my method list is blue. I am trying to use all different types of css to achieve this. My external works fine as that is the red one but, my two types of internal don't seem to change the other lists.
<!DOCTYPE html>
<html>
<head>
<style>
ol {color: blue;
font-style: italic;
}
</style>
<title>Emily's Cooking Page</title>
<link rel="stylesheet" href="demo1.css" />
</head>
<body>
<h1>Cooking for Students</h1>
<p>This page will show you how to make basic <b>macaroni</b> with all shop bought ingredients & how to store it properly</p>
<img src="macaroni.jpg" width="104" height="142">
<table>
<tr><td>prep: 5 minutes</td></tr>
<tr><td>cook: 30 minutes</td></tr>
<tr><td>difficulty: easy</td></tr>
<tr><td>quantity made: 3 to 4 meals</td></tr>
</table>
<h2>ingredients</h2>
<p>all found in Morrisons supermarkets</p>
<ul style="color:green;">
<li>250g pasta</li>
<li>300g cheese sauce</li>
</ul>
<h2>equipment</h2>
<ul>
<li>saucepan</li>
<li>wooden spoon</li>
<li>oven with hob</li>
<li>two to three tubs</li>
</ul>
<h2>method</h2>
<ol>
<li>On oven, turn hob to high heat. Fill a large saucepan with water and place on hob, allow water to begin boiling.</li>
<li>Once water is boiling, put all 250g of pasta into the saucepan and begin stirring with a wooden spoon.</li>
<li>Boiling pasta for 20 minutes or until soft. Use a knife or fork to test how hard the pasta is.</li>
<li>Take the saucepan off the hob and turn the hob down to a low heat. Using a sieve, drain all the water out of the saucepan and place pasta back into saucepan.</li>
<li>Place saucepan back on the hob and add 300g of cheese sauce to saucepan.</li>
<li>Mix the cheese sauce and pasta for 5 minutes</li>
<li>Turn hob off. Spread the macaroni into two or three separate tubs and allow them to cool down. Alternatively, you can eat one serving straight after cooking.</li>
<li>Once cooled down, place in fridge. To eat, place in microwave for 1 minute and a half, stir, then another minute (you can even add grated cheese on top after stirring).</li>
<li>After two days, move tubs to the freezer, to de-frost, place tub back in fridge and allow for one day of defrosting in fridge before microwaving and serving.</li>
</ol>
<p>Other Recipes:</p>
BBC GoodFood Macaroni Recipe
<p></p>
Food Network Macaroni Recipes
</body>
</html>
The following rule applies to all ordered lists.
ol {
color: blue;
font-style: italic;
}
Therefore, all ol should have blue color.
The ingredients list is a ul and has the inline styling of green color:
<ul style="color:green;">
<li>250g pasta</li>
<li>300g cheese sauce</li>
</ul>
Following your way, in order to apply the red color to the equipment list you can write:
<ul style="color: red">
<li>saucepan</li>
<li>wooden spoon</li>
<li>oven with hob</li>
<li>two to three tubs</li>
</ul>
However, I would suggest to create three classes for each color.
For example,
.color-blue {
color: blue;
}
.color-red {
color: red;
}
.color-green {
color: green;
}
<ul class="color-green;">
<li>250g pasta</li>
<li>300g cheese sauce</li>
</ul>
<ul class="color-red;">
<li>saucepan</li>
<li>wooden spoon</li>
<li>oven with hob</li>
<li>two to three tubs</li>
</ul>
<ol class="color-blue">
<li>On oven, turn hob to high heat. Fill a large saucepan with water and place on hob, allow water to begin boiling.</li>
...
...
</ol>

How to get element which has particular following-sibling element?

I want to select P element which has 'ul' as immediate following-sibling from below sample xml.
<root>
<p>abc</p>
<br>
<p>def</p>
<br>
<p>FEATURES</p>
<ul>
<li>design</li>
<li>softness</li>
</ul>
<p>SIZING</p>
<ul>
<li>17'' x 24''</li>
<li>20'' x 32''</li>
<li>24'' x 38''</li>
</ul>
<p>CONSTRUCTION & CARE</p>
<ul>
<li>Nylon</li>
<li>Latex backing</li>
<li>Machine wash</li>
<li>Made in the USA</li>
</ul>
<p>SUSTAINABILITY FEATURES</p>
</root>
I have tried this //root/p[following-sibling::ul] xpath but didn't get desired answer.
Try this one to get output:
//p[following-sibling::*[position()=1 and self::ul]]
"//root/ul/preceding-sibling::p[1]"
I don't think this needs an explanation :), it's already understandable.

XPath selection by value

I want to get a value of "square" (for example, 201). I tried to do so, as described here, but it doesn't work:
./li[attributeTitle='Этаж']
Html code:
<div class = "A">
<ui class = "B">
<li>
<span class = "attributeTitle"> Floor </span>
<span class = "attributeValue"> 3 </span>
</li>
<! A random more items "li" >
<li>
<span class = "attributeTitle"> Square </span>
<span class = "attributeValue"> 201 </span>
</li>
<li>
<span class = "attributeTitle"> Nrooms </span>
<span class = "attributeValue"> 4 </span>
</li>
</ui>
</div>
Thanks for any help.
You can use contains() function in xpath to check whether text contains some string:
"//div[#class='attributeTitle'][contains(text(),'Square')]"
This gets you this node:
<span class = "attributeTitle"> Square </span>
To get the value node that is right below it you can use following-sibling::span:
"//div[#class='attributeTitle'][contains(text(),'Square')]/following-sibling::span[1]"
And adding [1] to indicate that we want only the first sibling in case there are more than one sibling. You can also use [class='attributeValue'] instead to indicate that we only want siblings that have this particular class, or not use anything at all there if you trust there will only be 1 sibling.

iMacros - TAG specific element with XPATH

and thank you in advance for taking a minute of your valuable time to solve this puzzle and educate me on the topic.
(please forgive my terminology)
I am using the following code in iMacros for Firefox to select an element on the site, which works fine, as long as the element exists and is in the same order.
TAG XPATH=".//*[#id='contacts']/ul/li[1]/div/ul/li[1]" EXTRACT=TXT
Which in this case would result in "New York, NY"
From:
<div id="contacts" class="article expanding_group">
<div class="article-header">
<!-- Public Company = Block. Public Name/Title = Restricted. -->
<ul class="list">
<li class="list_item">
<div class="list_item_content contact-detail">
<div class="edit expanded">
<ul>
<li class="name"> New York, NY </li>
<li class=" ellipsis">
http://www.a24films.com
</li>
<li class="info ">
+1 646 568 6015
<span class="attributes">phone</span>
</li>
<li class="info ellipsis">
info#a24films.com
</li>
<li class="address ">601 West 26th Street</li>
<li class="address ">Suite 1740</li>
<li class="address "> New York, NY 10001 </li>
<li class="address ">USA</li>
<li class="address ">
</ul>
</div>
However, if the field is missing, it will skip to the next field which will, in essence, result in data being inserted into the incorrect row.
E.g. if I am expecting columns "name, phone, address", and it is missing phone, it will result in "name, address, blank".
I can see it I want only when list item 1's class="name", so my question is: is there a way to specify that I want the list item number 1 that contains "name" in class?
I have tried a variation of strings to no avail, but I woulf imaging something like this is possible:
TAG XPATH=".//*[#id='contacts']/ul/li[1]/div/ul/li[1]/name" EXTRACT=TXT
Thank you for your time,
Reinaldo
You can try the following code:
TAG XPATH=".//*[#id='contacts']/ul/li[1]/div/ul/li[#class='name'][1]" EXTRACT=TXT
Try this Xpath:
.//*[#id='contacts']//li[#class='name'][1]
I don't think #Shugar's code will work.

How to get span class text using jsoup

I am using jsoup HTML parser and trying to travel into span class and get the text from it but Its returning nothing and its size always zero. I have pasted small part of HTML source . pls help me to extract the text.
<div class="list_carousel">
<div class="rightfloat arrow-position">
<a class="prev disabled" id="ucHome_prev" href="#"><span>prev</span></a>
<a class="next" id="ucHome_next" href="#"><span>next</span></a>
</div>
<div id="uc-container" class="carousel_wrapper">
<ul id="ucHome">
<li modelID="587">
<h3 class="margin-bottom10"> Ford Figo Aspire</h3>
<div class="border-dotted margin-bottom10"></div>
<div>Estimated Price: <span class="cw-sprite rupee-medium"></span> 5.50 - 7.50 lakhs</div>
<div class="border-dotted margin-top10"></div>
</li>
<li modelID="899">
<h3 class="margin-bottom10"> Chevrolet Trailblazer</h3>
<div class="border-dotted margin-bottom10"></div>
<div>Estimated Price: <span class="cw-sprite rupee-medium"></span> 32 - 40 lakhs</div>
<div class="border-dotted margin-top10"></div>
</li>
I have tried below code:
Elements var_1=doc.getElementsByClass("list_carousel");//four classes with name of list_carousel
Elements var_2=var_1.eq(1);//selecting first div class
Elements var_3 = var_2.select("> div > span[class=cw-sprite rupee-medium]");
System.out.println(var_3 .eq(0).text());//printing first result of span text
please ask me , if my content was not very clear to you. thanks in advance.
There are several things to note about your code:
A) you can't get the text of the span, since it has no text in the first place:
<div>Estimated Price:
<span class="cw-sprite rupee-medium"></span>
5.50 - 7.50 lakhs
</div>
See? The text is in the div, not the span!
B) Your selector "> div > span[class=cw-sprite rupee-medium]" is not really robust. Classes in HTML can occur in any order, so both
<span class="cw-sprite rupee-medium"></span>
<span class="rupee-medium cw-sprite"></span>
are the same. Your selector only picks up the first. This is why there is a class syntax in css, which you should use instead:
"> div > span.cw-sprite.rupee-medium"
Further you can leave out he first > if you like.
Proposed solution
Elements lcEl = doc.getElementsByClass("list_carousel").first();
Elements spans = lcEl.select("span.cw-sprite.rupee-medium");
for (Element span:spans){
Element priceDiv = span.parent();
System.out.println(priceDiv.getText());
}
Try
System.out.println(doc.select("#ucHome div:nth-child(3)").text());