How to find the total number of elements/tags present under specific tag ?
<div id="mainTag class='mainTag'>
<div id="subMainTag1" class="subMainTag1">
<div id="subTag1" class="subTag1">
<div some inner tags again>
<div some inner tags again>
<div id="subTag1" class="subTag1">
<div some inner tags again>
<div some inner tags again>
<div id="subTag1" class="subTag1">
<div some inner tags again>
<div some inner tags again>
<div id="subTag1" class="subTag1">
<div some inner tags again>
<div some inner tags again>
I am looking for div tags having id and class subTag1.As per snippet provided above, i need to get the count value as 4.
verifyXpathCount does not return the counts.
storeXpathCount | //div[#id='mainTag']/div[#id='subMainTag1']/div | count
echo ${count}
storeXpathCount | //div[#id='mainTag']/div[#id='subMainTag1']//div | count
echo ${count}
storeXpathCount | //div[#id='mainTag']/div[#id='subMainTag1']/* | count
echo ${count}
All above returns 0, Nothing returns actual value 4. Not sure, what i am missing here.
Selenium IDE/web-driver:python , anything is fine.
ANSWER:
storeXpathCount working fine. I had missed to select frame.
Get Matching XPath Count also works fine in Robot Framework.
Adding to kjhughes's answer, since he didn't understand you were trying to achieve this using Robot Framework. It wasn't that clear, to his defense.
Using the XPath he provided, you could use the Xpath Should Match X Times keyword. Something like this:
XPath Should Match X Times //div[#id='mainTag']/* 4
If you need to store the retrieved matching count, you can use the quite similar keyword, Get Matching XPath Count, like this:
${count}= Get Matching XPath Count //div[#id='mainTag']/*
This XPath,
count(//div[#id='mainTag']/*)
will return the number of child elements under the div element with id attribute value of mainTag.
Related
This is a html snippet:
<input value="1" style="width: 90%;" type="text"></th><th style="cursor: default;" class=" filter">
<input value="2" class="tooltip" style="font-size: 0.8em; width: 90%;" placeholder="Datum" title="Datumsfilter
Mögliche Operatoren: < | > | <= | >= | <> < | > | <= | >= | <> | ..
Beispiele:
2016 | 2016-03 | 2016-03-24 (nur Jahr[-Monat[-Tag]])
>2015-02 | <=2016-09-15 (ab/bis angegebenem Jahr[-Monat[-Tag]] inkl./exkl.)
2016-03..2016-04-15 (angegebener Bereich)
<>2016-03 (ungleich)" type="text">
I must extract the value and it is possible that the type attribute is in any order.
/(?=<input.*?type="text"[^>]*?>).*?value="([^"]*)/
Works fine for
<input value="1" style="width: 90%;" type="text"></th><th style="cursor: default;" class=" filter">
But it breaks on ">" inside the title attribute from the second. How I can fix this?
Why not use
/\<input.{1,}?value="(.{1,}?)"/
it's a less complex: Just fetch the first "value"-tag (greedy quantifier) after each "input"-tag. Then get the value.
Note: I chose the greedy quantifier {1,}? instead of the * here to make sure, that the next occurrence of value will be selected and not any later occurrence.
But as mentioned: There might be better solutions than using regex here, for example if you are using php (? I don't know if you do ?). Depending on which language you are using you might have to change the regex-expression a little bit...
https://regex101.com/r/kB3wR2/1
This is Fragile...
It can be broken, circumvented and violated...
It is dangerous to use it...
Good luck for all who ignore these warnings...
There are problems galore to encounter and ways to pick nits out the ying yang, but if you have well formed HTML... ... ...
you can try: <input(?: (?:value=(['"])(?<value>(?:(?!\1).)*)\1|\w+=(['"])(?:(?!\3).)*\3))*>
And you can mess around with it here, if you dare.
I try to find all seconds tds among the descendants of div with the specified id, i.e. 22 and 222. The first solution that comes to my mind was:
//div[#id='indicator']//td[2]
but it selects only the first table cell, i.e. 22 but not both 22 and 222.
Then I replaced // with /descendant-or-self::node()/ and got the same result (obviously). But when I removed '-or-self' the xpath expression started to work as expected
test1 = test_tree.xpath(u"//div[#id='indicator']/descendant-or-self::node()/td[2]")
print len(test1) #prints 1 (first one: 22)
test1 = test_tree.xpath(u"//div[#id='indicator']/descendant::node()/td[2]")
print len(test1) #prints 2 (22 and 222)
Here is test HTML
<html>
<body>
<div id='indicator'>
<table>
<tbody>
<tr>
<th>1</th>
<th>2</th>
<th>3</th>
</tr>
<tr>
<td>11</td>
<td>22</td>
<td>33</td>
</tr>
<tr>
<td>111</td>
<td>222</td>
<td>333</td>
</tr>
</tbody>
</table>
</div>
</body>
</html>
I'm wondering why both expressions don't work identically since all the tds are descendants of div element no matter div included or not.
I think you have found a bug in your XPath processor.
I think I've found the cause of this issue:
http://www.w3.org/TR/xpath20/#id-errors-and-opt
"In some cases, a processor can determine the result of an expression without accessing all the data that would be implied by the formal expression semantics. For example, the formal description of filter expressions suggests that $s[1] should be evaluated by examining all the items in sequence $s, and selecting all those that satisfy the predicate position()=1. In practice, many implementations will recognize that they can evaluate this expression by taking the first item in the sequence and then exiting."
So there is no remedy. It's xpath processor implementation dependent however I still don't understand why //div[#id='indicator']/descendant-or-self::node()/td[2] and //div[#id='indicator']/descendant::node()/td[2] produce different results.
I developed a web page contains the HTML you provided in your question.
When you use this xpath:
.//div[#id='indicator']//tr/td[2]
It works as expected and the result is:
[u'<td>22</td>', u'<td>222</td>']
However, according to your comment, you were asking when .//td[2] doesn't work. The reason is .//td gives you a list of all the td(s) in your DOM. Adding an index such as [2] will result in the second td in that list
To sum up:
These are the results of applying .//td and .//td[2] respectively:
and if you want to take the text inside these tds, you should add /text() as the following:
Update:
The OP said:
So why then //div[#id='indicator']/descendant::node()/td[2] produces ['22', '222']? According to your comment: "Adding an index such as [2] will result in the second td in that list" it should populate only ['22'].
I will try to explain what is going on here:
descendant:node() doesn't equal to //
the equal to // is: descendant-or-self::node()
It is explained at W3C specification:
I hope this code could help you:
Is it possible to use schematron to ensure that the list items are in alphanumeric order?
<ul>
<li>1</li>
<li>a</li>
<li>d</li>
<li>g</li>
</ul>
Many thanks!
Yes, it is possible. You can use something like this example rule that reports all <li> elements whose value is lower than (lt) their previous <li> sibling value.
<sch:rule context="li">
<sch:report test=". lt preceding-sibling::li[1]">
This li value is lower than his previous li sibling value.
</sch:report>
</sch:rule>
I've got a cfoutput outputting some query data to display a product list on my page.
<ul class="row">
<cfoutput query="mycontent" startrow="#url.startrow#" maxrows="#url.maxrows#">
<li class="span-3">item data here</li>
<cfif mycontent.currentrow MOD 3 IS 3>
</ul><ul class="row">
</cfif>
</cfouptut>
I am trying to make it appear as a new row, with a new set of <ul> tags, when the items equal 3. This way I can have it neatly displayed on my page.
Each time it loads, it won't do this correctly. Instead it keeps the content within the top most <ul> tags.
How I can get this to be structured in a better way?
You want MOD to be 0 as MOD returns the remainder. That's how you know you are on a row divisible by 3 because the remainder equals 0.
<ul class="row">
<cfoutput query="mycontent" startrow="#url.startrow#" maxrows="#url.maxrows#">
<li class="span-3">item data here</li>
<cfif mycontent.currentrow MOD 3 eq 0>
</ul><ul class="row">
</cfif>
</cfouptut>
MOD or %
[Modulus]: Return the remainder after a number is divided by a divisor. The result has the same sign as the divisor. The value to the right of the operator should be an integer; using a non-numeric value causes an error, and if you specify a real number, ColdFusion ignores the fractional part (for example, 11 MOD 4.7 is 3).
I'm using pugixml to parse the following xml:
<td class="title">
<div class="random" />
Link1
</td>
<td class="title">
<div class="random" />
Link2
</td>
etc...
I want the value of every 'a href' in a td class ="title" (which appears an indeterminate number of times) but only the first such instance.
I am using the following code to try and get these values:
pugi::xpath_node_set link_nodes = list_doc.select_nodes("//td[#class='title']");
for (pugi::xpath_node_set::const_iterator it = link_nodes.begin();it != link_nodes.end();++it)
{
pugi::xpath_node single_link_node = *it;
std::cout << single_link_node.node().select_single_node("//a").node().attribute("href").value()<<std::endl;
}
which doesn't seem to work (it outputs number of times but with a value that doesn't even seem to appear within that element).
Thanks.
"//a" selects all "a" nodes in the document; you probably meant ".//a" that selects all "a" nodes in the subtree.
You can also use one XPath expression instead of multiple:
//td[#class='title']//a[1]
This selects the first tag for each td - i.e. [1] only applies to //a, not to the full expression.