How to get the second element in the list - c#

I have question how can I get second value (next value) of unixDate? How could I achieve this??
getData window:
public static List<Tuple<string, string>> euDataDaily(string url)
{
var aTuple = new List<Tuple<string, string>> { };
WebClient c = new WebClient();
var data = c.DownloadString(url);
JObject o = JObject.Parse(data);
string conditionCode="";
string unixDate = "";
string dayTemp="";
foreach (var result in o["daily"])
{
unixDate = (string)result["dt"];
string day = unixDate;
if (unixDate.Equals(day))
{
dayTemp = (string)result["temp"]["day"];
}
if (unixDate.Equals(day))
{
foreach (var res in result["weather"])
{
conditionCode = (string)res["description"];
}
}
}
aTuple.Add(Tuple.Create(dayTemp, conditionCode));
return aTuple;
}
EDIT: I need to get second "dt" value.
Data:
{"lat":56.94,"lon":24.1,"timezone":"Europe/Riga","timezone_offset":10800,"daily":[{"dt":1617703200,"sunrise":1617680352,"sunset":1617729143,"temp":{"day":6,"min":-1.1,"max":7.55,"night":1.3,"eve":5.46,"morn":-1.1},"feels_like":{"day":2.15,"night":-6.52,"eve":1.56,"morn":-6.52},"pressure":993,"humidity":61,"dew_point":-0.83,"wind_speed":6.05,"wind_deg":241,"weather":[{"id":600,"main":"Snow","description":"light snow","icon":"13d"}],"clouds":75,"pop":0.58,"snow":0.11,"uvi":2.12},
{"dt":1617789600,"sunrise":1617766591,"sunset":1617815670,"temp":{"day":6.78,"min":-0.52,"max":7.42,"night":1.41,"eve":6.13,"morn":-0.52},"feels_like":{"day":3.71,"night":-4.96,"eve":3.57,"morn":-4.96},"pressure":1001,"humidity":40,"dew_point":-5.88,"wind_speed":4.67,"wind_deg":216,"weather":[{"id":600,"main":"Snow","description":"light snow","icon":"13d"}],"clouds":15,"pop":0.62,"snow":0.22,"uvi":2.03},{"dt":1617876000,"sunrise":1617852830,"sunset":1617902197,"temp":{"day":4.38,"min":-0.44,"max":5.07,"night":1.3,"eve":4.02,"morn":0.62},"feels_like":{"day":-0.01,"night":-2.81,"eve":0.96,"morn":-2.81},"pressure":1009,"humidity":53,"dew_point":-4.45,"wind_speed":6.28,"wind_deg":323,"weather":[{"id":803,"main":"Clouds","description":"broken clouds","icon":"04d"}],"clouds":77,"pop":0.2,"uvi":2.27},
{"dt":1617962400,"sunrise":1617939069,"sunset":1617988724,"temp":{"day":6.12,"min":0.14,"max":7.58,"night":5.43,"eve":7.04,"morn":0.3},"feels_like":{"day":2.03,"night":-4.37,"eve":3.1,"morn":-4.37},"pressure":1015,"humidity":55,"dew_point":-2.05,"wind_speed":6.78,"wind_deg":207,"weather":[{"id":803,"main":"Clouds","description":"broken clouds","icon":"04d"}],"clouds":78,"pop":0.17,"uvi":2.38},{"dt":1618048800,"sunrise":1618025309,"sunset":1618075252,"temp":{"day":6.91,"min":4.2,"max":8.85,"night":5.84,"eve":8.85,"morn":4.2},"feels_like":{"day":4.17,"night":0.35,"eve":6.67,"morn":0.35},"pressure":1014,"humidity":74,"dew_point":2.54,"wind_speed":4.07,"wind_deg":216,"weather":[{"id":500,"main":"Rain","description":"light rain","icon":"10d"}],"clouds":100,"pop":0.39,"rain":0.49,"uvi":2.56},{"dt":1618135200,"sunrise":1618111550,"sunset":1618161779,"temp":{"day":4.54,"min":4.48,"max":5.66,"night":5.14,"eve":5.09,"morn":5.29},"feels_like":{"day":2.15,"night":5.29,"eve":2.3,"morn":5.29},"pressure":1017,"humidity":96,"dew_point":4,"wind_speed":2.74,"wind_deg":358,"weather":[{"id":501,"main":"Rain","description":"moderate rain","icon":"10d"}],"clouds":100,"pop":1,"rain":10.84,"uvi":3},
{"dt":1618221600,"sunrise":1618197791,"sunset":1618248307,"temp":{"day":10.63,"min":4.78,"max":11.88,"night":4.78,"eve":7.64,"morn":7.95},"feels_like":{"day":9.99,"night":5.74,"eve":4.6,"morn":5.74},"pressure":1017,"humidity":86,"dew_point":8.42,"wind_speed":3.31,"wind_deg":190,"weather":[{"id":500,"main":"Rain","description":"light rain","icon":"10d"}],"clouds":100,"pop":0.98,"rain":4.16,"uvi":3},
{"dt":1618308000,"sunrise":1618284033,"sunset":1618334834,"temp":{"day":5.87,"min":2.34,"max":7.02,"night":3.39,"eve":5.9,"morn":2.34},"feels_like":{"day":2.87,"night":-2.08,"eve":3.91,"morn":-2.08},"pressure":1027,"humidity":55,"dew_point":-2.38,"wind_speed":4.11,"wind_deg":268,"weather":[{"id":500,"main":"Rain","description":"light rain","icon":"10d"}],"clouds":90,"pop":0.2,"rain":0.11,"uvi":3}]}
Thanks for response.

Related

My C# WPF webscraper returns error when more than one result is found

I am working on a WPF XAML application that scrapes certain websites for products. I have the search part working and it finds what I'm looking for. But as soon as there is more then 1 result I get a System.InvalidoperationException. I use a ObservableCollection to put the results into a <ListBox>.
Here is the search method:
private static ObservableCollection<EntryModel> _entries = new ObservableCollection<EntryModel>();
public static ObservableCollection<EntryModel> LoadCollectionData
{
get { return _entries; }
set { _entries = value; }
}
public static void PrehmSearchResults(string SearchQuery)
{
HtmlWeb web = new HtmlWeb();
try
{
string ZoekOpdracht = SearchQuery.Replace(" ", "+");
HtmlDocument doc = web.Load("https://www.prehmshop.de/advanced_search_result.php?keywords=" + ZoekOpdracht);
var title = doc.DocumentNode.CssSelect("div.header_cell > a").Single().InnerText;
var links = doc.DocumentNode.CssSelect("a.product_link");
var productLink = new List<string>();
var productTitle = new List<string>();
foreach (var item in links)
{
if (item.Attributes["href"].Value.Contains(".html"))
{
productLink.Add(item.Attributes["href"].Value);
productTitle.Add(title);
}
}
var TitleAndLink = productLink.Zip(productTitle, (l, t) => new { productLink = l, productTitle = t });
foreach (var nw in TitleAndLink)
{
var product = new List<EntryModel>();
var adDetails = new EntryModel
{
Title = nw.productTitle,
Link = nw.productLink
};
Debug.Print(adDetails.ToString());
var ZoekOpdrachtInTitle = adDetails.Title.ToLower().Contains(ZoekOpdracht.ToLower());
if (ZoekOpdrachtInTitle)
{
_entries.Add(adDetails);
}
}
}
So I found the solution without changing too much code. thanks for the help from #PaulSinnema.
The link is part of the title so I only had to change
var title = doc.DocumentNode.CssSelect("div.header_cell > a").ToList();
And I had to change the foreach loop:
foreach (var item in title)
{
if (item.Attributes["href"].Value.Contains(".html"))
{
productLink.Add(item.Attributes["href"].Value);
productTitle.Add(item.InnerText);
}
}

XDocument get Element value with Namespace (RSS Feed)

Im working on getting some values from an RSS feed but i am having difficulties getting a value which has the namespace in the element tag. I've tried adding the namespace to the lookup of the value but i always get null
Any idea on how this is achieved?
Feed
https://wegotthiscovered.com/movies/feed/
Element
xmlns:content="http://purl.org/rss/1.0/modules/content/"
Namespace
content:encoded
public async Task<bool> GetNewsFeeds()
{
Database db = new Database();
Dictionary<string, string> dictionary = new Dictionary<string, string>();
dictionary.Add("https://wegotthiscovered.com/movies/feed/", "Movie");
dictionary.Add("https://wegotthiscovered.com/blu-ray/feed/", "Blu-ray");
dictionary.Add("https://wegotthiscovered.com/reviews/feed/", "Reviews");
dictionary.Add("https://wegotthiscovered.com/featured/feed/", "Featured");
dictionary.Add("https://wegotthiscovered.com/galleries/feed/", "Galleries");
db.DeletMovieNews();
foreach (var pair in dictionary.ToList())
{
try
{
if (PhysicalDevice.HasInternetConnection())
{
XDocument doc = XDocument.Load(pair.Key);
XNamespace nsSys = "http://purl.org/rss/1.0/modules/content/";
var entries = (from item in doc.Descendants("item")
select new Movie_News
{
Content = item.Element(nsSys + "encoded").Value, // ISSUE HERE
Link = item.Element("link").Value,
PublishedDate = item.Element("pubDate").Value,
Title = item.Element("title").Value,
Description = item.Element("description").Value,
GroupName = "News",
FeedName = pair.Value
});
List<Movie_News> newsCollection = entries.ToList();
if (newsCollection.Count() != 0)
{
using (var rateGate = new RateGate(40, TimeSpan.FromSeconds(10)))
{
rateGate.WaitToProceed();
foreach (Movie_News item in newsCollection)
{
string regex = #"((http|ftp|https):\/\/)?([\w_-]+(?:(?:\.[\w_-]+)+))([\w.,#?^=%&:\/~+#-]*[\w#?^=%&\/~+#-])?";
Match match = Regex.Match(item.Description, regex);
if (match.Success)
{
item.ImageUrl = match.Value;
item.B64Image = await DownloadImage(item.ImageUrl);
}
item.Description = item.Description.Remove(0, item.Description.IndexOf("</div>"));
item.Description = item.Description.Replace("</div>","");
db.InsertNewsData(item);
}
}
}
return true;
}
}
catch(Exception ex)
{
return false;
}
}
return true;
}
}
Typical , soon as i completed the write up, its working now

Multiple List return using Tuple class in C#

I have a class Helper with 2 methods
public static List<string> GetCountryName()
{
List<string> CountryName = new List<string>();
using (var sr = new StreamReader(#"Country.txt"))
{
string line;
while ((line = sr.ReadLine()) != null)
{
int index = line.LastIndexOf(" ");
CountryName.Add(line.Substring(0, index));
}
}
return CountryName;
}
public static List<string> GetCountryCode()
{
List<string> CountryCode = new List<string>();
using (var sr = new StreamReader(#"Country.txt"))
{
string line;
while ((line = sr.ReadLine()) != null)
{
int index = line.LastIndexOf(" ");
CountryCode.Add(line.Substring(index + 1));
}
}
return CountryCode;
}
I bind these return values with my WPF ComboBox as follows
ddlCountryName.ItemsSource = Helper.GetCountryName();
ddlCountryCode.ItemsSource = Helper.GetCountryCode();
I wanted to return these List in a single method and went through these links
Tuple Class
https://stackoverflow.com/a/10278769
After going through it I tries like this but could not able to make it properly from line no-3 Tuple<List<string>> CountryName = new Tuple<List<string>>
public static Tuple<List<string>,List<string>> GetAllData()
{
Tuple<List<string>> CountryName = new Tuple<List<string>>
List<string> CountryCode = new List<string>();
using (var sr = new StreamReader(#"Country.txt"))
{
string line;
while ((line = sr.ReadLine()) != null)
{
int index = line.LastIndexOf(" ");
CountryName.Add(line.Substring(0, index));
CountryCode.Add(line.Substring(index + 1));
}
}
return CountryName;
return CountryCode;
}
Please help me to return List item wise and bind in the ItemsSource as per the below code
ddlCountryName.ItemsSource = Helper.GetCountryName();
try this (not tested)
public static Tuple<List<string>, List<string>> GetAllData()
{
List<string> CountryName = new List<string>();
List<string> CountryCode = new List<string>();
using (var sr = new StreamReader(#"Country.txt"))
{
string line;
while ((line = sr.ReadLine()) != null)
{
int index = line.LastIndexOf(" ");
CountryName.Add(line.Substring(0, index));
CountryCode.Add(line.Substring(index + 1));
}
}
return new Tuple<List<string>, List<string>>(CountryName,CountryCode);
}
A Tuple is a pack of two or more values and the types of these values are specified through generic parameters when you create a Tuple object. You are creating a Tuple of a single value, which has no meanings. Try creating it like this:
Tuple<List<string>, List<string>> CountryName = new Tuple<List<string>, List<string>>();
Also note that a function cannot have more than one return statements. You should add both your lists to the Tuple object and then return it in one go.
Your final function will be something like (keep your two existing functions and create a new function that calls them):
public static Tuple<List<string>,List<string>> GetAllData()
{
return new Tuple<List<string>, List<string>>(GetCountryName(), GetCountryCode());
}
An alternate approach:
public static List<Tuple<string, string>> GetAllData()
{
List<Tuple<string, string>> Result = new List<Tuple<string, string>>();
using (var sr = new StreamReader(#"Country.txt"))
{
string line;
while ((line = sr.ReadLine()) != null)
{
int index = line.LastIndexOf(" ");
var Name = line.Substring(0, index);
var Code = line.Substring(index + 1);
Result.Add(new Tuple<string, string>(Name, Code));
}
}
return Result;
}
In the first case, you do your binding directly to the Tuple members:
ddlCountryName.ItemsSource = Result.Item1;
ddlCountryCode.ItemsSource = Result.Item2;
In the second case, you can do some further linq to get your individual lists from the returned object:
ddlCountryName.ItemsSource = Result.Select(x => x.Item1).ToArray();
ddlCountryCode.ItemsSource = Result.Select(x => x.Item2).ToArray();

Confused about how get value from DictionaryList at specific index

I am using a DictionaryList to keep some values coming from an xml file
this is the my xml file
<DnsServers>
<Dns>
<Name>Google</Name>
<Value>8.8.8.8,8.8.4.4</Value>
</Dns>
<Dns>
<Name>Telekom</Name>
<Value>195.175.39.39,195.175.39.40</Value>
</Dns>
</DnsServers>
and then populating a combobax just key values like this way .
void ReadFromDnsServerList()
{
_nameValueDictionary = new Dictionary<string, string>();
//var list = new List<string>();
XDocument doc = XDocument.Load("DnsServerList.xml");
if (doc.Root != null)
{
var keyValueXml = from c in doc.Root.Descendants("Dns")
select new
{
name = c.Element("Name").Value,
value = c.Element("Value").Value
};
foreach (var info in keyValueXml)
{
_nameValueDictionary.Add(info.name,info.value);
}
foreach (KeyValuePair<string, string> item in _nameValueDictionary)
{
cmbDns.Items.Add(item.Key);
}
}
}
I am wondering that How can I get corresponding dns value inside cmbDns_SelectedIndexChanged
change event somethinglike this
name=Google value =8.8.8.8,8.8.4.4
Try this:
void ReadFromDnsServerList()
{
_nameValueDictionary = new Dictionary<string, string>();
XDocument doc = XDocument.Load("DnsServerList.xml");
if (doc.Root != null)
{
var keyValueXml = from c in doc.Root.Descendants("Dns")
select new
{
name = c.Element("Name").Value,
value = c.Element("Value").Value
};
foreach (var info in keyValueXml)
{
_nameValueDictionary.Add(info.name, info.value);
}
cmbDns.DisplayMember = "Key";
cmbDns.ValueMember = "Value";
cmbDns.DataSource = _nameValueDictionary.ToArray();
}
}
I hope it helps.

Anonymous collection initializer for a dictionary

Is it possible to implicitly declare next Dictionary<HyperLink, Anonymous>:
{ urlA, new { Text = "TextA", Url = "UrlA" } },
{ urlB, new { Text = "TextB", Url = "UrlB" } }
so I could use it this way:
foreach (var k in dic)
{
k.Key.Text = k.Value.Text;
k.Key.NavigateUrl = k.Value.Url;
}
?
How about:
var dict = new[] {
new { Text = "TextA", Url = "UrlA" },
new { Text = "TextB", Url = "UrlB" }
}.ToDictionary(x => x.Url);
// or to add separately:
dict.Add("UrlC", new { Text = "TextC", Url = "UrlC" });
However, you could just foreach on a list/array...
var arr = new[] {
new { Text = "TextA", Url = "UrlA" },
new { Text = "TextB", Url = "UrlB" }
};
foreach (var item in arr) {
Console.WriteLine("{0}: {1}", item.Text, item.Url);
}
You only need a dictionary if you need O(1) lookup via the (unique) key.
Yes, but only with great workaround, and only within a method.
This is how you can do it:
static Dictionary<TKey, TValue> NewDictionary<TKey, TValue>(TKey key, TValue value)
{
return new Dictionary<TKey, TValue>();
}
public void DictRun()
{
var myDict = NewDictionary(new { url="a"},
new { Text = "dollar", Url ="urlA"});
myDict.Add(new { url = "b" }, new { Text = "pound", Url = "urlB" });
myDict.Add(new { url = "c" }, new { Text = "rm", Url = "urlc" });
foreach (var k in myDict)
{
var url= k.Key.url;
var txt= k.Value.Text;
Console.WriteLine(url);
Console.WriteLine(txt);
}
}
You can refer to this SO question for more info.

Categories

Resources