C# Selenium Extract Data from span with partial ID - c#

I am trying to create a proper XPATH syntax in C# Selenium to extract an order number on a web page. Here is what I've tried to far to grab the order number shown in the screen shot. All of these have errored out on me.
var result = driver.FindElement(By.XPath("//span[#id^='order-number-'")).Text;
var result = driver.FindElement(By.XPath("//div[#id='a-column a-span7']/h5")).Text;
var result = driver.FindElement(By.XPath("//div[#id='a-column a-span7']/span[#class='a-text-bold']")).Text;
Below is the inspection from Chrome. I am trying to grab the order number, but it will not always be the same so I cannot hard code the span id.

The driver.FindElement(By.XPath("//span[#id^='order-number-'")) would definitely match nothing since ^= is not a valid operator in XPath language. Plus, you are not closing the square brackets.
Instead, if you want to have a shorter and more readable version, use a CSS selector:
driver.FindElement(By.CssSelector("span[id^=order-number]"))
Here ^= means "starts with".
If you want to stay with XPath, use starts-with() function:
driver.FindElement(By.XPath("//span[starts-with(#id, 'order-number-')]"))

You can try this out:
var result = driver.FindElement(By.XPath("//span[contains(#id, 'order-number-')]")).Text;
It uses a "contains" on the span ID. Let me know if this helps.

Related

How to extract number from text, which is between <br> <<b> - Xpath

I do not know how to do than, so I do not post any my code :/
<div class="style2 f_left">Wyprawa do <b>Tana</b><br>Czas trwania: <b>32</b> minut.<br>Szansa powodzenia: <b>75 %</b>.<br></div>
From this div I need to extract number 32(it's random generated)
XPath is an option, but since you don't post any requirement for it I suggest some other solutions.
You could use a regular expression to get the number:
<b>(\d+?)<\/b>
The answer will be in the first group.
Since you're working with HTML you could also use HtmlAgilityPack or similar solutions to step through it and get the value from there.
If you are using javascript you could do as below:
var num = parseInt($('#DivIdHere').text().match(/\d+/)[0], 10);
just get all text from < div > element and substring everything between "Czas trwania:" and "minut", no need to use complex xPath

Xpath does not recognize regex parts

I am new to this and I am trying to understand the usage of selenium and XPath
string exp = "//*[#id=\"g_1_bHwVovAN\"]/td[2]";
var dateTime = chromeDriver.FindElementsByXPath(exp);
With this code, I can only take 1 element. How can I change this "bHwVovAN" part, so I can reach the all that kinds of elements on the website.
string exp = "//*[#id=\"g_1_[^[0-9+]]\"]/td[2]";
var dateTime = chromeDriver.FindElementsByXPath(exp);
I tried to use regex, but It did not work. It did not recognize regex parts. Also, I looked at the other posts, and tried to use matches, and also did not work. How can I solve it?
If I did not write clear and correct way, I am also new to English. Sorry
There is a matches() function in XPath 2.0 that would solve your issue, but selenium doesn't support this XPath version.
You can try below to match elements with id attribute that starts with "g_1_":
string exp = "//*[starts-with(#id,\"g_1_\")]/td[2]";

Find elements on webpage with Selenium

I have XPath
/html/body/div[#id='page']/div[#id='page-inner']/div[#id='main-box']/div[#class='in1']/div[#id='content-and-context']/div[#id='content']/div[#class='under-bar']/table[#class='flights']/tbody/tr[#id='flight-932539']/td[2]:
But flight-number are changes. Can I find Elements with part XPath ?
I use foreach() and write data for every flight.
this is html code:
First thing first: don't use absolute path. Even the smallest change in the html invalidate the path, especially in dynamic applications. Your xpath could easily be //tr[#id='flight-932539']/td[2]
As for your question, you can use contains() for partial id
//tr[contains(#id, 'flight-')]/td[2]
As Guy mentioned xpath above, for same you can easily use findElements to find all the flight details and then according perform you actions using for loop.
List<WebElement> WebElements = driver.findElements(By.xpath("//tr[contains(#id, 'flight-')]/td[2]");
for(WebElement element : WebElements){
//perform any operation like for click you can use
element.getText();
}
Above example is in JAVA you can do same in C# as well.

Matching and replacing function expressions

I need to do some very light parsing of C# (actually transpiled Razor code) to replace a list of function calls with textual replacements.
If given a set containing {"Foo.myFunc" : "\"def\"" } it should replace this code:
var res = "abc" + Foo.myFunc(foo, Bar.otherFunc( Baz.funk()));
with this:
var res = "abc" + "def"
I don't care about the nested expressions.
This seems fairly trivial and I think I should be able to avoid building an entire C# parser using something like this for every member of the mapping set:
find expression start (e.g. Foo.myFunc)
Push()/Pop() parentheses on a Stack until Count == 0.
Mark this as expression stop
replace everything from expression start until expression stop
But maybe I don't need to ... Is there a (possibly built-in) .NET library that can do this for me? Counting is not possible in the family of languages that RE is in, but maybe the extended regex syntax in C# can handle this somehow using back references?
edit:
As the comments to this answer demonstrates simply counting brackets will not be sufficient generally, as something like trollMe("(") will throw off those algorithms. Only true parsing would then suffice, I guess (?).
The trick for a normal string will be:
(?>"(\\"|[^"])*")
A verbatim string:
(?>#"(""|[^"])*")
Maybe this can help, but I'm not sure that this will work in all cases:
<func>(?=\()((?>/\*.*?\*/)|(?>#"(""|[^"])*")|(?>"(\\"|[^"])*")|\r?\n|[^()"]|(?<open>\()|(?<-open>\)))+?(?(open)(?!))
Replace <func> with your function name.
Useless to say that trollMe("\"(", "((", #"abc""de((f") works as expected.
DEMO

Read specific text from page into string array in C#

I've tried this and searched for help but I cannot figure it out. I can get the source for a page but I don't need the whole thing, just one string that is repeated. Think of it like trying to grab only the titles of articles on a page and adding them in order to an array without losing any special characters. Can someone shed some light?
You can use a Regular Expression
to extract the content you want from a string, such as your html string.
Or you can use a DOM parser such as
Html Agility Pack
Hope this helps!
You could use something like this -
var text = "12 hello 45 yes 890 bye 999";
var matches = System.Text.RegularExpressions.Regex.Matches(text,#"\d+").Cast<Match>().Select(m => m.Value).ToList();
The example pulls all numbers in the text variable into a list of strings. But you could change the Regular Expression to do something more suited to your needs.
if the page is well-formed xml, you could use linq to xml by loading the page into an XDocument and using XPath or another way of traversing to the element(s) you desire and loading what you need into the array for which you are looking (or just use the enumerable if all you want to do is enumerate). if the page is not under your control, though, this is a brittle solution that could break at any time when subtle changes could break the well-formedness of the xml. if that's the case, you're probably better off using regular expressions. eiither way, though, the page could be changed under you and your code suddenly won't work anymore.
the best thing you could do would be to get the provider of the page to expose what you need as a webservice rather than trying to scrape their page.

Categories

Resources