hello guys i am try to print the output of two element data simultaneously
Document document2 = Jsoup.parse(webPage2);
Document document22 = Jsoup.parse(webPage2);
Elements links2 = document2.select("a.yschttl");
Elements links22 = document22.select("div.abstr");
can we include both a.yschttl and div.abstr or...
for (Element link2 : links2) {
out.println(link2);
}
can we include two say links2 and links22 in same for loop...
or how to achive it...
You can do something like:
for (int i = 0; i < links2.size(); i++) {
out.println(links2.get(i));
out.println(links22.get(i));
}
But in this case you will get IndexOutOfBoundsException if size of links22 higher than size of links2.
What do you want to achieve?
If you are just trying to select both at the same time, you can do something like this:
for (Element link : document.select("a.yschttl, div.abstr") {
out.println(link);
}
If you are trying to make two selections and outputting those values in tandem, you will have to do something like #vacuum suggests, but being careful of the lengths of the lists.
A side note, you don't have to parse the document twice to make two selections. You can parse once and select twice.
Related
There are 2 drop-down lists. Each has a similar meaning, for example, "Jorge". Lists in different modules. When I need to fill in, for example, a list that is lower in the tree, then the first match is taken along the XPath path, on an undisclosed list.
Not lists, but values in drop-down lists!
There are 2 drop-down lists. Each has a similar meaning, for example, "Jorge". Lists in different modules. When I need to fill in, for example, a list that is lower in the tree, then the first match is taken along the XPath path, on an undisclosed list.
Not lists, but values in drop-down lists!
I wanted to implement it in Java this way:
Example:
if (findElement(By.xpath("(//example//example)")).isDisplayed()) {
findElement(By.xpath("(//example//example)")).click();
}
But in this case, the element is not displayed.
How to implement a search of all values similar to the XPath path in order to get the one that is displayed?
I tried to do something like this: (//example//example)1 (//example//example)[2] (//example//example)[3]
In my case, we have that 1 - the element does not exist [2] - exists, but is not displayed (isDisplayed = false) [3] - exists, is displayed (isDisplayed = true)
iterating through the values in the loop for [n] cannot be implemented, because, for example, the value 1 is not.
Described as difficult as possible :D. Excuse me.
If someone understands my nonsense, please help me. How to implement my requirement?
enter image description here
UPD:
The problem was solved (for me) by substituting the first value into the expression ()"{1}" immediately.
Now I'm interested in why I get an exception after the first iteration:
Method threw 'org.openqa.selenium.ElementNotInteractableException' exception.
Code:
int number = 1;
String option = "(//ul[contains(#style, 'display: block')]//li//span[contains(text(),'" + valueField + "') or strong[contains(text(),'" + valueField.toUpperCase() + "')]])";
findElement(By.xpath(option+"["+number+"]"));
String[] words = valueField.split(" ");
StringBuilder builder = new StringBuilder();
for (int i = 0; i < words.length; i++) {
builder.append(words[i]);
setFieldByLabel(nameModule, nameLabel, builder.toString());
fastWaitLoading();
for (int y = 0; y < 10; y++) {
if (findElement(By.xpath(option+"["+number+"]")).isDisplayed()) {
new Actions(browser.getWebDriver())
.moveToElement(findElement(option))
.click()
.build()
.perform();
break;
}
number++;
}
}
So I am trying to fully understand your question, and I don't. What I would recommend for a situation like this is, iterate through all elements by creating a list with: findElements(By.xpath ... )
This way you will get a list of webelements and you can iterate through them. Then apply a foreach, assert if element is displayed (it exists as it has been found with findElements) and you should be able to interact with it.
Yeah, everything is in a prominent place)
Missed it
new actions(browser.getWebDriver()) .moveToElement(findElement(**option**)) .click() .build() .perform(); break;
Here
new actions(browser.getWebDriver())
.moveToElement(findElement(**option + "[" + number+"]"**))
.click()
.build()
.perform();
break;
I am using JSoup for the first time to parse the HTML two elements based on class. I am able to successfully pull the data of each. The problem I am having is formatting the data the way I want. The data I am pulling is for a link hit counter.
The final result I want is something like
https://yadayadayada.com 1,
https://yadayadayada.com 4,
... etc
instead I am getting
https://yadayadayada.com https://yadayadayada.com 1, 4,
This is how I am getting my current output
Document doc = Jsoup.connect(link).get();
Elements links = doc.getElementsByClass("details shorlinkUrl");
Elements count = doc.getElementsByClass("highlight listUrl").append(",");
String counter = count.text();
String linkname = links.text();
System.out.println(prettyname.toString()+count.toString());
String results = new StringBuilder(14).append(prettyname).append(counter).toString();
Any ideas or direction is greatly apperciated!!
When you call text() method on Elements object, you get concatenated text from all elements in this collection. You can iterate over separate elements and get text from elements separately and manipulate it accordingly.
Elements links = doc.getElementsByClass("details shorlinkUrl");
Elements count = doc.getElementsByClass("highlight listUrl");
if(links.size()!= count.size()) {
throw new IllegalStateException("Think about this situation");
}
for(int i = 0; i< links.size(); i++) {
System.out.println(links.get(i).text() + " " +count.get(i).text()+ ",");
}
I am still learning xpath and I am trying to skip the first row of a table because the first row has no values. I am not having success i searched through stack over flow and could not find anyone with a similar issue. My code is below:
int reqIndex = 0;
do {
List<WebElement> payDates = driver.findElements(By.xpath("//tr[starts-with(#id,'changeStartWeekGrid_row_')]/td[contains(#id,'_cell_4')/span]"));
System.out.println(payDates);
for(WebElement pd:payDates) {
LocalDate localDate = LocalDate.now();
java.util.Date d = new SimpleDateFormat("yyyy-MM-dd").parse(localDate.toString());
String str = pd.getText();
if ( str >= (d) ){ // still figuring this out
driver.findElement(By.xpath( "//tr[#id='changeStartWeekGrid_row_'" + reqIndex +"])/TBODY[#id='changeStartWeekGrid_rows_tbody']/TR[7]/TD[1]/DIV[1]/DIV[1]/DIV[1]")).click();
break;
}else{
reqIndex++;
}
}
}while(reqIndex < 7 ); /// do this 7 times
Thread.sleep(10000);
This is the part i am trouble shooting right now
List<WebElement> payDates = driver.findElements(By.xpath("//tr[starts-with(#id,'changeStartWeekGrid_row_')]/td[contains(#id,'_cell_4')/span]"));
System.out.println(payDates);
Thread.sleep(10000);
The xpath works the problem is that it is selecting the first row and it has no values row zero does so it needs to skip the first row and go to row zero.
when i run the code i get this message:
( //tr[starts-with(#id,'changeStartWeekGrid_row_')]/td[contains(#id,'_cell_4')/span])
ilter expression must evaluate to nodeset.
the row highlighted is the row i am trying to skip
cell 4 image
-----radio button html code below
<div id="changeStartWeekGrid.store.rows[5].cells[0]_widget" tabindex="0" class="revitRadioButton dijitRadio" onfocus="var registry = require('dijit/registry'); registry.byId('changeStartWeekGrid').changeActiveCell('changeStartWeekGrid_row_5_cell_0', event);" onblur="var registry = require('dijit/registry'); registry.byId('changeStartWeekGrid').blurActiveCell('changeStartWeekGrid.store.rows[5]', 'changeStartWeekGrid.store.rows[5].cells[0]');"><div class="revitRadioButtonIcon"></div></div>
---radio button picture
Try to use XPath
//table[#id='changeStartWeekGrid_rows_table']//tr[preceding-sibling::tr]
to select all tr nodes except the firts one
You can also use position() as below:
//table[#id='changeStartWeekGrid_rows_table']//tr[position()>1]
Note that in XPath indexation starts from 1 and so [position()>1] predicate means return all sibling nodes skiping the first one
You may also use
//tr[starts-with(#id,'changeStartWeekGrid_row_') and not(starts-with(#id, 'changeStartWeekGrid_row_column'))]/td[5]/span
I have a program which reads an XML file using Java DOM and processes certain element. For example, here is part of the document I am looking at:
<Flow>
<Id>306</Id>
<Type>Simple</Type>
<FlowContent Width="0.2000000000000000111">
<P Id="523"><T xml:space="preserve" Id="652">A spouse’s pension would be paid equal to <O Id="351"/>% of your Core pension at date of death.</T>
</P>
</FlowContent>
(Note: this is exported from a program called GMC Inspire Designer, so I have no control over its format.)
I can process most elements fine, but have issues with text content which also contains elements. In the example above, another layout object <O Id="351"/> (referencing another piece of text or a variable) occurs in the body of the text.
I can look up this element and retrieve it using the ID number. This is the element linked in the above snippet:
<Variable>
<Id>351</Id>
<Name>CAMT44</Name>
What I would then like to do is output information from the linked node (e.g., I could look up the node with ID 351 and retrieve the name etc. then display this information in place of where the element appears within the string).
I currently look up children and store the ID in a string array like so:
NodeList nl = e.getElementsByTagName("O");
sa = new String[nl.getLength()]; // Set up new array to hold child ids
for (int i = 0; i < nl.getLength(); i++) {
sa[i] = nodeToElement(nl.item(i)).getAttribute("Id");
}
I'm very much a Java beginner, so I've been wondering if DOM was the correct choice for this project. Perhaps I should have used SAX instead, but as I don't have much XML experience, I'm not sure which best suits my needs and, as I mentioned, I have managed to do most of the things I need, it's just this last tricky bit that I'm stuck on.
Currently my output looks like this:
IF CR.SCHEME == "EXCT" PRINT:
"A spouse’s pension would be paid equal to % of your Core pension at
date of death, ignoring the fact that you may have chosen to convert
part of your pension into a lump sum at retirement."
Child flow: 351
It would be great if there is some way to do this using DOM. Apologies if anything is unclear, I'm new to most of this.
You should be able to do something like this:
String output = "";
for (int i = 0; i < nl.getLength(); i++) {
Node n = nl.item(i);
if(n.getNodeType() == Node.TEXT_NODE) {
output += n.getTextContent();
} else if (n.getNodeType() == Node.ELEMENT_NODE && n.getNodeName().equals("O")) {
output += lookup(doc, ((Element)n).getAttribute("id"));
}
}
System.out.println(output);
The lookup method is something you would need to implement yourself but it would look something like this:
private static String lookup(Document doc, String id) {
return "<IMPLEMENT_LOOKUP_HERE>";
}
I'll try to explain this as best I can. I have an ArrayList of String's. I am trying to implement server-side paging for a webapp. I am restricted to the number of items per page (6 in this case) which are read from this ArrayList. The ArrayList is, lets say, the entire catalog, and each page will take a section of it to populate the page. I can get this working just fine when there are enough elements to fill the particular page, its when we hit the end of the ArrayList where there will be less than 6 items remaining for that pages segment. How can I check if the ArrayList is on its last element, or if the next one doesn't exist? I have the following code (in pseudo-ish code):
int enterArrayListAtElement = (numberOfItemsPerPage * (requestedPageNumber - 1));
for (int i = 0; i < numberOfItemsPerPage; i++) {
if (!completeCatalog.get(enterArrayListAtElement + i).isEmpty() {
completeCatalog.get(enterArrayListAtElement + i);
}
}
The if in the code is the problem. Any suggestions will be greatly appreciated.
Thanks.
It sounds like you want:
if (enterArrayListAtElement + i < completeCatalog.size())
That will stop you from trying to fetch values beyond the end of the list.
If that's the case, you may want to change the bounds of the for loop to something like:
int actualCount = Math.min(numberOfItemsPerPage,
completeCatalog.size() - enterArrayListAtElement);
for (int i = 0; i < actualCount; i++) {
// Stuff
}
(You may find this somewhat easier to format if you use shorter names, e.g. firstIndex instead of enterArrayListAtElement and pageSize instead of numberOfItemsPerPage.)
Can't you just get
completeCatalog.size()
and compare it to i? i.e to answer the question "is there an ith element" you say
if (i<completeCatalog.size())
You just need to add a second expression to look whether the end of the list was reached already:
int enterArrayListAtElement = (numberOfItemsPerPage * (requestedPageNumber - 1));
for (int i = 0; i < numberOfItemsPerPage; i++) {
if (enterArrayListAtElement + i < completeCatalog.size() && !completeCatalog.get(enterArrayListAtElement + i).isEmpty() {
completeCatalog.get(enterArrayListAtElement + i);
}
}
An ArrayList has the method of size(), which returns the number of elements within the List.
Therefore, you can use this within the if statement to check you've not went too far.
For example,
if(enterArrayListAtElement + i < completeCatalog.size()) {
...
}