How to find an element by using two xpaths - xpath

I have the next xpaths
//span[text() = 'someText']//..//div//input
and
//span[text() = 'someText']//..//div//input[#role = 'someRole']
I want to get something like this:
protected SelenideElement someElement = $x(//span[text() = 'someText']//..//div//input(|#role = 'somerole'))
I want to get my element in the both ways:
if there is nothing after an //input
and if there is [#role = 'someRole']
Should I use "|" for this or maybe there are various solutions?

Related

Using OR in CodeIgniter Active Record's Delete Method

I need to be able to convert the following to Ci's active record delete method but I don't know how to use the OR in the delete statement. Could you please tell me how I'd do this correctly?
$this->db->query("DELETE FROM friend WHERE userid_friends = '{$userid}' AND friendId_friends = '{$targetedUserId}' OR userid_friends = '{$targetedUserId}' AND friendId_friends = '{$userid}' ");
I guess your trying this:
$this->db->query("DELETE FROM friend WHERE
( userid_friends = '{$userid}' AND friendId_friends = '{$targetedUserId}') OR
( userid_friends = '{$targetedUserId}' AND friendId_friends = '{$userid}') ");
(note the added parentheses for the two AND clauses)
But actually your not using CI's "DELETE" method just a query.
Using active record delete would be something like:
$this->db->where("userid_friends = '{$userid}' AND friendId_friends = '{$targetedUserId}'");
$this->db->or_where("userid_friends = '{$targetedUserId}' AND friendId_friends = '{$userid}'");
$this->db->delete('friend');
For debugging of complex queries I recommend you to use
echo $this->db->last_query();
As it shows you exactly how the final query was rendered by the Active record methods.

Get query string in Google CSE v2

I am using Google CSE v2, and I need to get the query that the user entered. The problem is that it is ajax, and the query is not in the url.
Does anyone know a solution?
Thanks
First off, when you create the search box, you need to give it a 'gname' attribute so you can identify it in your javascript, like so:
<gcse:searchbox gname="storesearch"></gcse:searchbox>
<gcse:searchresults gname="storesearch"></gcse:searchresults>
Or, if you're using the html5 style tags (which you should unless you have a reason not to):
<div class="gcse-searchbox" data-gname="storesearch"></div>
<div class="gcse-searchresults" data-gname="storesearch"></div>
(Replace 'storesearch' with whatever name you want to use to identify this custom search.)
More info on that here: https://developers.google.com/custom-search/docs/element#supported_attributes
Then, you can access the custom search element and get the current query like so:
var cseElement = google.search.cse.element.getElement('storesearch'),
query = cseElement.getInputQuery();
or if you don't need the reference to the element anymore, obviously that could be combined into one line:
var query = google.search.cse.element.getElement('storesearch').getInputQuery();
The docs for that part are here: https://developers.google.com/custom-search/docs/element#cse-element
I know this is already answered correctly. But for those also looking for a simple JS function to achieve this, here you go. Pass it the name of the variable you want to extract from the query string.
var qs = (function(a) {
if (a == "") return {};
var b = {};
for (var i = 0; i < a.length; ++i) {
var p=a[i].split('=');
if (p.length != 2) continue;
b[p[0]] = decodeURIComponent(p[1].replace(/\+/g, " "));
}
return b;
})(window.location.search.substr(1).split('&'));

HTMLAgilityPack ChildNodes index works, named node does not

I am parsing an XML API response with HTMLAgilityPack. I am able to select the result items from the API call.
Then I loop through the items and want to write the ChildNodes to a table. When I select
ChildNodes by saying something like:
sItemId = dnItem.ChildNodes(0).innertext
I get the proper itemId result. But when I try:
sItemId = dnItem.ChildNodes("itemId").innertext
I get "Referenced object has a value of 'Nothing'."
I have tried "itemID[1]", "/itemId[1]" and a veriety of strings. I have tried SelectSingleNode and ChildNodes.Item("itemId").innertext. The only one that has worked is using the index.
The problem with using the index is that sometimes child elements are omitted in the results and that throw off the index.
Anybody know what I am doing wrong?
HtmlAgilityPack.HtmlDocument htmlDoc = new HtmlDocument();
htmlDoc.LoadHtml(#webHTMLeditor.TextXhtml);
HtmlNodeCollection tableRows = htmlDoc.DocumentNode.SelectNodes("//tr");
for (int i = 0; i < tableRows.Count; i++)
{
HtmlNode tr = tableRows[i];
HtmlNode[] td = new HtmlNode[2];
string xpath = tr.XPath + "//td";
HtmlNodeCollection cellRows = tr.SelectNodes(#xpath);
//td[0] = tr.ChildNodes[1];
//td[1] = tr.ChildNodes[3];
try
{
td[0] = cellRows[0];
td[1] = cellRows[1];
}
catch (Exception)
{ }
//etc
}
The code is used to extract data from a table, row by row, by cell per row.
I used the existing xpath and I altered it acording to my needs.
Good luck!

Reading the next line using LINQ and File.ReadAllLines()

I have a file which represents items, in one line there's Item GUID followed by 5 lines describing the item.
Example:
Line 1: Guid=8e2803d1-444a-4893-a23d-d3b4ba51baee name= line1
Line 2: Item details = bla bla
.
.
Line 7: Guid=79e5e39d-0c17-42aa-a7c4-c5fa9bfe7309 name= line7
Line 8: Item details = bla bla
.
.
I am trying to access this file first to get the GUIDs of the items meet the criteria provided using LINQ e.g. where line.Contains("line1").. This way I will get the whole line, I will extract the GUID from there, I want to pass this GUID to another function which should access the file "again", find that line (where line.Contains("line1") && line.Contains("8e2803d1-444a-4893-a23d-d3b4ba51baee") and reads the next 5 lines starting from that line.
Is there any efficient way to do so?
I don't think it really makes sense to use LINQ entirely given the requirements of what you need to do and given that the index of the line in the array is fairy integral. I would also recommend doing everything in one pass - opening the file multiple times won't be as efficient as just reading everything once and processing it immediately. As long as the file is structured as well as you describe, this won't be terribly difficult:
private void GetStuff()
{
var lines = File.ReadAllLines("foo.txt");
var result = new Dictionary<Guid, String[]>();
for (var index = 0; index < lines.Length; index += 6)
{
var item = new
{
Guid = new Guid(lines[index]),
Description = lines.Skip(index + 1).Take(5).ToArray()
};
result.Add(item.Guid, item.Description);
}
}
I tried a couple different ways to do this with LINQ but nothing allowed me to do a single scan of the file. For this scenario you're talking about I would go down to the Enumerable level and use the GetEnumerator like this:
public IEnumerable<LogData> GetLogData(string filename)
{
var line1Regex = #"Line\s(\d+):\sGuid=([0123456789abcdefg]{8}-[0123456789abcdefg]{4}-[0123456789abcdefg]{4}-[0123456789abcdefg]{4}-[0123456789abcdefg]{12})\sname=\s(\w*)";
int detailLines = 4;
var lines = File.ReadAllLines(filename).GetEnumerator();
while (lines.MoveNext())
{
var line = (string)lines.Current;
var match = Regex.Match(line, line1Regex);
if (!match.Success)
continue;
var details = new string[detailLines];
for (int i = 0; i < detailLines && lines.MoveNext(); i++)
{
details[i] = (string)lines.Current;
}
yield return new LogData
{
Id = new Guid(match.Groups[2].Value),
Name = match.Groups[3].Value,
LineNumber = int.Parse(match.Groups[1].Value),
Details = details
};
}
}

LINQ: Entity string field contains any of an array of strings

I want to get a collection of Product entities where the product.Description property contains any of the words in a string array.
It would look something like this (result would be any product which had the word "mustard OR "pickles" OR "relish" in the Description text):
Dim products As List(Of ProductEntity) = New ProductRepository().AllProducts
Dim search As String() = {"mustard", "pickles", "relish"}
Dim result = From p In products _
Where p.Description.Contains(search) _
Select p
Return result.ToList
I already looked at this similar question but couldn't get it to work.
Since you want to see if search contains a word which is contained in the description of p you basically need to test for each value in search if it is contained in the description of p
result = from p in products
where search.Any(val => p.Description.Contains(val))
select p;
This is c# syntax for the lambda method since my vb is not that great
Dim result = From p in products _
Where search.Any(Function(s) p.Description.Contains(s))
Select p
You can use a simple LINQ query, if all you need is to check for substrings:
var q = words.Any(w => myText.Contains(w));
// returns true if myText == "This password1 is weak";
If you want to check for whole words, you can use a regular expression:
Matching against a regular expression that is the disjunction of all the words:
// you may need to call ToArray if you're not on .NET 4
var escapedWords = words.Select(w => #"\b" + Regex.Escape(w) + #"\b");
// the following line builds a regex similar to: (word1)|(word2)|(word3)
var pattern = new Regex("(" + string.Join(")|(", escapedWords) + ")");
var q = pattern.IsMatch(myText);
Splitting the string into words with a regular expression, and testing for membership on the words collection (this will get faster if you use make words into a HashSet instead of a List):
var pattern = new Regex(#"\W");
var q = pattern.Split(myText).Any(w => words.Contains(w));
In order to filter a collection of sentences according to this criterion all you have to do its put it into a function and call Where:
// Given:
// bool HasThoseWords(string sentence) { blah }
var q = sentences.Where(HasThoseWords);
Or put it in a lambda:
var q = sentences.Where(s => Regex.Split(myText, #"\W").Any(w => words.Contains(w)));
Ans From => How to check if any word in my List<string> contains in text by #R. Martinho Fernandes

Resources