I have a xml like below with root as rail
<rail>
<timetable>
<trainParts>
<trainPart id="tp_1" name="1" timetablePeriodRef="ttp_2012_13" categoryRef="cat_Commuter" processStatus="planned" trainNumber="1">
<operatingPeriodRef ref="Daily" />
<ocpsTT>
<ocpTT ocpType="begin" ocpRef="ocp_SWH">
<sectionTT trackInfo="SWH-DM" />
</ocpTT>
<ocpTT ocpType="stop" ocpRef="ocp_SE">
<times arrival="16:16:00" departure="16:18:00" scope="scheduled" />
<sectionTT trackInfo="SE-DM" />
</ocpTT>
.
.
.
so on
</ocpsTT>
</trainPart>
</trainParts>
</timetable>
</rail>
Now like this there are many train numbers whose details I have to parse in one go.
I can parse one child and its attributes at a time using linq but i want to parse all the childs and its elements.
Say for trainNumer="1" i need to get
categoryRef
processStatus
operatingPeriodRef
ocpType
ocpRef
trackInfo
arrival
departure
NOTE: In some cases times tag containing departure arrival is not there
I did try to write the code as below:
public void trainDetails(string trainNumber)
{
var xdoc = XDocument.Load("Rail.xml");
XNamespace ad = "http://www.rail.org/schemas/2009";
var train = (from t in xdoc.Root.Elements(ad + "timetable")
let d = t.Element(ad + "trainParts").Element("trainPart")
where (string)t.Attribute("number") == trainNumber
select new
{
operatingPeriod=(from s1 in d.Elements(ad+"operatingPeriodRef")
operatingref=(string)s1.Attribute("ref")
}).ToList()
}
select new
{
trainOcpsTT= (from s2 in d.Elements(ad + "ocpsTT").Elements(ad+"ocpTT")
select new
{
ocpType=(string)s2.Attribute("ocpType"),
ocpRef=(string)s2.Attribute("ocpRef")
}).ToList()
}).FirstOrDefault();
}
}
I am unable to frame the query properly..
Is it Possible to get all these in one xml linq query itself?How?
If not then which is the proper approach in this case..
Here is my proposal:
public class TrainInfo
{
public string categoryRef { get; set; }
public int trainNumber { get; set; }
public string processStatus { get; set; }
public string operatingPeriodRef { get; set; }
public List<ocpsTTs> ocpsTT { get; set; }
}
public struct ocpsTTs
{
public string ocpType;
public string ocpRef;
public string arrival;
public string departure;
public string scope;
public string trackInfo;
}
class Program
{
static void Main(string[] args)
{
TrainInfo ti = ProcessXml(#"XMLFile1.xml", 1);
}
static TrainInfo ProcessXml(string xmlfile, int trainnumber)
{
TrainInfo retVal;
try
{
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(xmlfile);
XNamespace xns = "http://www.rail.org/schemas/2009";
XDocument xdoc = System.Xml.Linq.XDocument.Parse(xmlDoc.InnerXml);
retVal =
(from c
in xdoc.Root.Elements(xns + "timetable").Elements(xns + "trainParts").Elements(xns + "trainPart")
where c.Attribute("trainNumber").Value.Equals(trainnumber.ToString())
select new TrainInfo
{
categoryRef = c.Attribute("categoryRef").Value,
trainNumber = Int32.Parse(c.Attribute("trainNumber").Value),
processStatus = c.Attribute("processStatus").Value,
operatingPeriodRef = c.Element(xns + "operatingPeriodRef").Attribute("ref").Value,
ocpsTT = (from tt in c.Elements(xns + "ocpsTT").Descendants(xns + "ocpTT")
let timeinfo = tt.Elements(xns + "times").Any()
select new ocpsTTs
{
ocpType = tt.Attribute("ocpType").Value,
ocpRef = tt.Attribute("ocpRef").Value,
arrival = timeinfo ? tt.Element(xns + "times").Attribute("arrival").Value : string.Empty,
departure = timeinfo ? tt.Element(xns + "times").Attribute("departure").Value : string.Empty,
scope = timeinfo ? tt.Element(xns + "times").Attribute("scope").Value : string.Empty,
trackInfo = tt.Element(xns + "sectionTT").Attribute("trackInfo").Value,
}).ToList()
}).FirstOrDefault();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
retVal = null;
}
return retVal;
}
}
Related
I'm trying to put my SQL rule in Linq , as my rule get generated from query builder and I need to filter my data based on rule , this is my simple example
class Program
{
static void Main(string[] args)
{
PromotionVm lObjPromVm = new PromotionVm();
for (int i = 1; i <= 5; i++)
{
PromotionList lObjPromList = new PromotionList();
lObjPromList.active_indicator = 1;
lObjPromList.principle_code = "a" + i;
lObjPromList.promotion_code = "b" + i;
lObjPromList.promotion_plan_number = 20 + i;
lObjPromList.promotion_type_code = 30 + i;
lObjPromList.start_date = DateTime.Now.AddDays(i);
lObjPromVm.promotion_list.Add(lObjPromList);
}
//var sqlRule= "promotion_type_code = 'expensive' AND Category IN('Food', 'Transportation', 'Shopping') AND(PaymentMode = 'Cash' OR PaymentMode = 'Debit Card' OR(Amount = 35))";
var sqlRule = "promotion_type_code = '33'";
// lObjPromVm.promotion_list.ToDataTable()
var lOutlut = lObjPromVm.promotion_list.Where(sqlRule);
}
}
class PromotionVm
{
public List<PromotionList> promotion_list { get; set; }
public PromotionVm()
{
promotion_list = new List<PromotionList>();
}
}
public class PromotionList
{
public string principle_code { get; set; }
public string promotion_code { get; set; }
public int promotion_plan_number { get; set; }
public int promotion_type_code { get; set; }
public DateTime start_date { get; set; }
public int active_indicator { get; set; }
}
I'm trying to use System.Linq.Dynamic.Core; but not working.
Can anyone suggest how I can filter my data by SQL rules?
same question was asked here How to use a string in the linq where clause?
but response what is given , its not working .
I was able to solve the problem , I just needed to convert to AsQueryable() .
var sqlRule = "promotion_type_code in (31,33) or (promotion_code=\"b2\")";
var lOutlut = lObjPromVm.promotion_list.AsQueryable().Where(sqlRule);
Starting from a table of daily fruit prices
fruits.csv
Day,Name,Kind,Price
2019-09-04,"apple","red",63.09
2019-09-04,"apple","yellow",52.14
2019-09-04,"orange","navel",41.18
2019-09-04,"orange","blood",41.18
2019-09-03,"apple","red",63.07
2019-09-03,"apple","yellow",52.11
2019-09-03,"orange","navel",41.13
2019-09-03,"orange","blood",41.13
I'd like to insert the reference prices by name and kind
fruit_ref_prices.csv
Name,Kind,Reference_Price
"apple","red",60.00
"apple","yellow",50.00
"orange","navel",40.00
"orange","blood",42.00
to result in the following table
Day,Name,Kind,Price,Reference_Price
2019-09-04,"apple","red",63.09,60.00
2019-09-04,"apple","yellow",52.14,50.00
2019-09-04,"orange","navel",41.18,40.00
2019-09-04,"orange","blood",41.18,42.00
2019-09-03,"apple","red",63.07,60.00
2019-09-03,"apple","yellow",52.11,50.00
2019-09-03,"orange","navel",41.13,40.00
2019-09-03,"orange","blood",41.13,42.00
The solution should be simple using C#'s built-in SQL-like syntax, and I'm sure the answer lies in one of the following tutorial pages:
Join clause
Perform custom join operations
Join by using composite keys
but I'm having a hard time identifying the syntax of this language.
In my attempt below instead of writing
join fruit_ref in fruit_refs on fruit.name equals fruit_ref.name
I should be able to write
join fruit_ref in fruit_refs on fruit.name equals fruit_ref.name
and fruit.kind equals fruit_ref.kind
but the Boolean expression is not accepted. Why?
My attempt is:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.IO;
namespace MyConsoleApplication
{
class Program
{
const string root = #"c:\path\to\here\";
const string file1_in = root + #"fruits.csv";
const string file2_in = root + #"fruit_ref_prices.csv";
static void Main(string[] args)
{
Fruit_Basket fruit_basket = new Fruit_Basket(file1_in, file2_in);
fruit_basket.PrintFruits();
}
}
public class Fruit
{
public DateTime day { get; set; }
public string name { get; set; }
public string kind { get; set; }
public decimal price { get; set; }
public Fruit(DateTime newFruit_day,
string newFruit_name,
string newFruit_kind,
decimal newFruit_price)
{
this.day = newFruit_day;
this.name = newFruit_name;
this.kind = newFruit_kind;
this.price = newFruit_price;
}
}
public class Fruit_Ref
{
public string name;
public string kind;
public decimal reference_price;
public Fruit_Ref(string newName, string newKind, decimal newRef_Price)
{
this.name = newName;
this.kind = newKind;
this.reference_price = newRef_Price;
}
}
public class Fruit_Basket {
public List<Fruit> fruits { get; set; }
public List<Fruit_Ref> fruit_refs { get; set; }
public Fruit_Basket(string file1_in, string file2_in) {
build_fruit_list(file1_in);
build_fruit_ref_list(file2_in);
}
public void build_fruit_list(string file_in)
{
fruits = new List<Fruit>();
int count = 0;
StreamReader reader = new StreamReader(file_in);
string line = "";
while ((line = reader.ReadLine()) != null)
{
if (++count > 1)
{
string[] splitLine = line.Split(new char[] { ',' }).ToArray();
var newFruit_day = DateTime.Parse(splitLine[0]);
var newFruit_name = splitLine[1];
var newFruit_kind = splitLine[2];
var newFruit_price = decimal.Parse(splitLine[3]);
Fruit newFruit = new Fruit(newFruit_day,
newFruit_name,
newFruit_kind,
newFruit_price);
fruits.Add(newFruit);
}
}
reader.Close();
}
public void build_fruit_ref_list(string file_in)
{
fruit_refs = new List<Fruit_Ref>();
int count = 0;
StreamReader reader = new StreamReader(file_in);
string line = "";
while ((line = reader.ReadLine()) != null)
{
if (++count > 1)
{
string[] splitLine = line.Split(new char[] { ',' }).ToArray();
var newFruit_name = splitLine[0];
var newFruit_kind = splitLine[1];
var newFruit_ref_price = decimal.Parse(splitLine[2]);
Fruit_Ref newFruit_ref = new Fruit_Ref(newFruit_name,
newFruit_kind,
newFruit_ref_price);
fruit_refs.Add(newFruit_ref);
}
}
reader.Close();
}
public void PrintFruits()
{
var innerJoinQuery =
from fruit in fruits
join fruit_ref in fruit_refs on fruit.name equals fruit_ref.name
select new { Day = fruit.day, Name = fruit.name, Kind = fruit.kind,
Price = fruit.price, Reference_Price = fruit_ref.reference_price };
Console.WriteLine($#"""Date"",""Name"",""Kind"",""Price"",""Ref Price""");
foreach (var i in innerJoinQuery)
{
Console.WriteLine($#"{i.Day},{i.Kind},{i.Price},{i.Reference_Price}");
}
}
}
}
You could also refactor your code to use the CsvHelper NuGet package for reading/writing CSV files.
First, You can make these classes to reflect the fruits, fruit references and final fruit structure.
public class Fruit
{
public string Day { get; set; }
public string Name { get; set; }
public string Kind { get; set; }
public string Price { get; set; }
}
public class FruitReferencePrice
{
public string Name { get; set; }
public string Kind { get; set; }
public string Reference_Price { get; set; }
}
public class FruitFinal
{
public string Day { get; set; }
public string Name { get; set; }
public string Kind { get; set; }
public string Price { get; set; }
public string ReferencePrice { get; set; }
public override string ToString()
{
return $"Day={Day},Name={Name},Kind={Kind},Price={Price},Reference_Price={ReferencePrice}";
}
}
Then you can make two methods to return the rows of each CSV file into List<Fruit> and List<FruitReferencePrice>.
private static IEnumerable<Fruit> BuildFruitList(string csvFilePath)
{
if (!File.Exists(csvFilePath))
{
throw new FileNotFoundException("Could not locate CSV at path " + csvFilePath, csvFilePath);
}
try
{
using var fileReader = File.OpenText(csvFilePath);
using var csv = new CsvReader(fileReader);
return csv.GetRecords<Fruit>().ToList();
} catch (Exception ex)
{
Console.WriteLine(ex.Message);
return Enumerable.Empty<Fruit>();
}
}
private static IEnumerable<FruitReferencePrice> BuildFruitReferenceList(string csvFilePath)
{
if (!File.Exists(csvFilePath))
{
throw new FileNotFoundException("Could not locate CSV at path " + csvFilePath, csvFilePath);
}
try
{
using var fileReader = File.OpenText(csvFilePath);
using var csv = new CsvReader(fileReader);
return csv.GetRecords<FruitReferencePrice>().ToList();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
return Enumerable.Empty<FruitReferencePrice>();
}
}
Then you can perform a grouped join and output the merged result.
var path1 = "PATH\\fruits.csv";
var path2 = "PATH\\fruit_ref_prices.csv";
var fruitList = BuildFruitList(path1);
var fruitReferencePrices = BuildFruitReferenceList(path2);
var groupedJoin = from fruit in fruitList
join fruit_ref in fruitReferencePrices
on new { fruit.Name, fruit.Kind } equals new { fruit_ref.Name, fruit_ref.Kind }
select new FruitFinal
{
Day = fruit.Day,
Name = fruit.Name,
Kind = fruit.Kind,
Price = fruit.Price,
ReferencePrice = fruit_ref.Reference_Price
};
foreach (var fruit in groupedJoin)
{
Console.WriteLine(fruit.ToString());
}
Merged results:
Day=2019-09-04,Name=apple,Kind=red,Price=63.09,Reference_Price=60.00
Day=2019-09-04,Name=apple,Kind=yellow,Price=52.14,Reference_Price=50.00
Day=2019-09-04,Name=orange,Kind=navel,Price=41.18,Reference_Price=40.00
Day=2019-09-04,Name=orange,Kind=blood,Price=41.18,Reference_Price=42.00
Day=2019-09-03,Name=apple,Kind=red,Price=63.07,Reference_Price=60.00
Day=2019-09-03,Name=apple,Kind=yellow,Price=52.11,Reference_Price=50.00
Day=2019-09-03,Name=orange,Kind=navel,Price=41.13,Reference_Price=40.00
Day=2019-09-03,Name=orange,Kind=blood,Price=41.13,Reference_Price=42.00
Please change the equals clause as on new { fruit.name, fruit.kind } equals new { fruit_ref.name, fruit_ref.kind }
Why you require this
The query has two anonymous types (one for left table and one for right table). So to compare those anonymous types, the linq statement should use new keyword
Query :
var innerJoinQuery = from fruit in fruits
join fruit_ref in fruit_refs on new { fruit.name, fruit.kind } equals new { fruit_ref.name, fruit_ref.kind }
select new { Day = fruit.day, Name = fruit.name, Kind = fruit.kind,
Price = fruit.price, Reference_Price = fruit_ref.reference_price };
I have class which gets info from Imdb.com about movie ant stores info in class variables.I have another class which writes info about movie in database. So, I want to make inheritence and get variables info and save into database. But I am getting error: 'FilmuBiblioteka.IMDb' does not contain a constructor that takes 0 arguments
Here is my code:
public class IMDb
{
public bool status { get; set; }
public string Id { get; set; }
public string Title { get; set; }
public string OriginalTitle { get; set; }
public string Year { get; set; }
public string Rating { get; set; }
public ArrayList Genres { get; set; }
public ArrayList Directors { get; set; }
public ArrayList Cast { get; set; }
public string Plot { get; set; }
public string Poster { get; set; }
public string PosterLarge { get; set; }
public string PosterFull { get; set; }
public string Runtime { get; set; }
public ArrayList Languages { get; set; }
public ArrayList Countries { get; set; }
public string ImdbURL { get; set; }
//Search Engine URLs
private string GoogleSearch = "http://www.google.com/search?q=imdb+";
private string BingSearch = "http://www.bing.com/search?q=imdb+";
private string AskSearch = "http://www.ask.com/web?q=imdb+";
private Func<string> toString;
private bool v;
//Constructor
public IMDb(string MovieName, bool GetExtraInfo = true)
{
string imdbUrl = getIMDbUrl(System.Uri.EscapeUriString(MovieName));
status = false;
if (!string.IsNullOrEmpty(imdbUrl))
{
parseIMDbPage(imdbUrl, GetExtraInfo);
}
}
public IMDb(Func<string> toString, bool v)
{
this.toString = toString;
this.v = v;
}
//Get IMDb URL from search results
private string getIMDbUrl(string MovieName, string searchEngine = "google")
{
string url = GoogleSearch + MovieName; //default to Google search
if (searchEngine.ToLower().Equals("bing")) url = BingSearch + MovieName;
if (searchEngine.ToLower().Equals("ask")) url = AskSearch + MovieName;
string html = getUrlData(url);
ArrayList imdbUrls = matchAll(#"<a href=""(http://www.imdb.com/title/tt\d{7}/)"".*?>.*?</a>", html);
if (imdbUrls.Count > 0)
return (string)imdbUrls[0]; //return first IMDb result
else if (searchEngine.ToLower().Equals("google")) //if Google search fails
return getIMDbUrl(MovieName, "bing"); //search using Bing
else if (searchEngine.ToLower().Equals("bing")) //if Bing search fails
return getIMDbUrl(MovieName, "ask"); //search using Ask
else //search fails
return string.Empty;
}
//Parse IMDb page data
private void parseIMDbPage(string imdbUrl, bool GetExtraInfo)
{
string html = getUrlData(imdbUrl + "combined");
Id = match(#"<link rel=""canonical"" href=""http://www.imdb.com/title/(tt\d{7})/combined"" />", html);
if (!string.IsNullOrEmpty(Id))
{
status = true;
Title = match(#"<title>(IMDb \- )*(.*?) \(.*?</title>", html, 2);
OriginalTitle = match(#"title-extra"">(.*?)<", html);
Year = match(#"<title>.*?\(.*?(\d{4}).*?\).*?</title>", html);
Rating = match(#"<b>(\d.\d)/10</b>", html);
Genres = matchAll(#"<a.*?>(.*?)</a>", match(#"Genre.?:(.*?)(</div>|See more)", html));
Directors = matchAll(#"<td valign=""top""><a.*?href=""/name/.*?/"">(.*?)</a>", match(#"Directed by</a></h5>(.*?)</table>", html));
Cast = matchAll(#"<td class=""nm""><a.*?href=""/name/.*?/"".*?>(.*?)</a>", match(#"<h3>Cast</h3>(.*?)</table>", html));
Plot = match(#"Plot:</h5>.*?<div class=""info-content"">(.*?)(<a|</div)", html);
Runtime = match(#"Runtime:</h5><div class=""info-content"">(\d{1,4}) min[\s]*.*?</div>", html);
Languages = matchAll(#"<a.*?>(.*?)</a>", match(#"Language.?:(.*?)(</div>|>.?and )", html));
Countries = matchAll(#"<a.*?>(.*?)</a>", match(#"Country:(.*?)(</div>|>.?and )", html));
Poster = match(#"<div class=""photo"">.*?<a name=""poster"".*?><img.*?src=""(.*?)"".*?</div>", html);
if (!string.IsNullOrEmpty(Poster) && Poster.IndexOf("media-imdb.com") > 0)
{
Poster = Regex.Replace(Poster, #"_V1.*?.jpg", "_V1._SY200.jpg");
PosterLarge = Regex.Replace(Poster, #"_V1.*?.jpg", "_V1._SY500.jpg");
PosterFull = Regex.Replace(Poster, #"_V1.*?.jpg", "_V1._SY0.jpg");
}
else
{
Poster = string.Empty;
PosterLarge = string.Empty;
PosterFull = string.Empty;
}
ImdbURL = "http://www.imdb.com/title/" + Id + "/";
if (GetExtraInfo)
{
string plotHtml = getUrlData(imdbUrl + "plotsummary");
}
}
}
/*******************************[ Helper Methods ]********************************/
//Match single instance
private string match(string regex, string html, int i = 1)
{
return new Regex(regex, RegexOptions.Multiline).Match(html).Groups[i].Value.Trim();
}
//Match all instances and return as ArrayList
private ArrayList matchAll(string regex, string html, int i = 1)
{
ArrayList list = new ArrayList();
foreach (Match m in new Regex(regex, RegexOptions.Multiline).Matches(html))
list.Add(m.Groups[i].Value.Trim());
return list;
}
//Strip HTML Tags
static string StripHTML(string inputString)
{
return Regex.Replace(inputString, #"<.*?>", string.Empty);
}
//Get URL Data
private string getUrlData(string url)
{
WebClient client = new WebClient();
Random r = new Random();
//Random IP Address
client.Headers["X-Forwarded-For"] = r.Next(0, 255) + "." + r.Next(0, 255) + "." + r.Next(0, 255) + "." + r.Next(0, 255);
//Random User-Agent
client.Headers["User-Agent"] = "Mozilla/" + r.Next(3, 5) + ".0 (Windows NT " + r.Next(3, 5) + "." + r.Next(0, 2) + "; rv:2.0.1) Gecko/20100101 Firefox/" + r.Next(3, 5) + "." + r.Next(0, 5) + "." + r.Next(0, 5);
Stream datastream = client.OpenRead(url);
StreamReader reader = new StreamReader(datastream);
StringBuilder sb = new StringBuilder();
while (!reader.EndOfStream)
sb.Append(reader.ReadLine());
return sb.ToString();
}
}
public class filmai : IMDb
{
public System.Data.DataSet gauticonnection
{
get
{ return gauti(); }
}
private System.Data.DataSet gauti()
{
System.Data.SqlClient.SqlConnection sqlConnection1;
System.Data.SqlClient.SqlDataAdapter da;
sqlConnection1 = new System.Data.SqlClient.SqlConnection(#"Data Source=(LocalDB)\v11.0;AttachDbFilename=C:\Users\Darius\Documents\Visual Studio 2013\Projects\FilmuBiblioteka\FilmuBiblioteka\duombaze.mdf");
da = new SqlDataAdapter("select * from filmai", sqlConnection1);
DataSet ds = new DataSet();
da.Fill(ds, "Table");
try
{
sqlConnection1.Open();
da.Fill(ds);
}
catch (Exception e)
{
throw;
}
finally
{
if (sqlConnection1.State == System.Data.ConnectionState.Open)
sqlConnection1.Close();
}
return ds;
}
public void prideti()
{
System.Data.SqlClient.SqlConnection sqlConnection1 = new System.Data.SqlClient.SqlConnection(#"Data Source=(LocalDB)\v11.0;AttachDbFilename=C:\Users\Darius\Documents\Visual Studio 2013\Projects\FilmuBiblioteka\FilmuBiblioteka\duombaze.mdf");
System.Data.SqlClient.SqlCommand cmd = new System.Data.SqlClient.SqlCommand();
cmd.CommandType = System.Data.CommandType.Text;
cmd.CommandText = "INSERT filmai (Id, Pavadinimas, Metai, trukme, salis, kalba, reitingas, zanras, aktoriai, link, plot, rezisieriai) VALUES (Id, Title, Year, Runtime, Countries, Languages, Rating, Genres, Cast, ImdbURL, Plot, Directors)";
cmd.Connection = sqlConnection1;
sqlConnection1.Open();
cmd.ExecuteNonQuery();
sqlConnection1.Close();
}
}
I'm getting error at this line: public class filmai : IMDb
As previously said in my comment the compliation error that you have is because the current constructor for your filmai class does not correctly call a constructor of your IMDb class.
To correctly inherit from a base class you must call it's constructor before your implemented constructor of the deriving class runs such as:
public filmai(string filmName)
: base(filmName, false)
{
}
This will call the base constructor of public IMDb(string MovieName, bool GetExtraInfo = true) with the film name that was provided to the filmai constructor and will say that it does not require extra information.
I'm not sure on your use-case though as it looks like filmai is purely for database access and IMDb is for requesting for a single film? But implementing a constructor on filmai and calling : base(...) will fix your issue just now.
i'm having a trouble with taking information from xml using linq in c# wpf application.
followings are the codes i use.
public class YouTubeInfo
{
public string LinkUrl { get; set; }
public string EmbedUrl { get; set; }
public string ThumbNailUrl { get; set; }
public string Title { get; set; }
public int Duration { get; set; }
}
public class YouTubeProvider
{
const string SEARCH = "http://gdata.youtube.com/feeds/api/videos?q={0}&alt=rss&start-index={1}&max-results={2}&v=1";
const string Most_popular = "http://gdata.youtube.com/feeds/api/standardfeeds/KR/most_popular?time=today&alt=rss&start-index={1}&max-results={2}&v=2";
//const string Entertainment = "https://gdata.youtube.com/feeds/api/standardfeeds/KR/most_popular_Entertainment?start-index=1&max-results=2";
#region Load Videos From Feed
public static int search_based;
static string search;
public static List<YouTubeInfo> LoadVideosKey(string keyWord, int start, int limit)
{
try
{
switch (search_based)
{
case 0: search = SEARCH; break;
case 1: search = Most_popular; break;
}
var xraw = XElement.Load(string.Format(search, keyWord, start, limit));
var xroot = XElement.Parse(xraw.ToString());
var links = (from item in xroot.Element("channel").Descendants("item")
select new YouTubeInfo
{
LinkUrl = item.Element("link").Value,
Title = item.Element("title").Value,
EmbedUrl = GetEmbedUrlFromLink(item.Element("link").Value),
ThumbNailUrl = GetThumbNailUrlFromLink(item),
Duration = GetDuration(item),
}).Take(limit);
return links.ToList<YouTubeInfo>();
}
catch (Exception e)
{
Trace.WriteLine(e.Message, "ERROR");
}
return null;
}
i want to take information from this xml
https://gdata.youtube.com/feeds/api/standardfeeds/KR/most_popular_Entertainment?start-index=1&max-results=2
Maybe better if you use SyndicationFeed. See the sample below:
Import needed namspaces
using System.ServiceModel.Syndication;
using System.Xml;
Load feed implementation
private static string GetAttributeFromGroup(SyndicationElementExtensionCollection seec, string elementName, string attributeName)
{
foreach (SyndicationElementExtension extension in seec)
{
XElement element = extension.GetObject<XElement>();
if (element.Name.LocalName == "group")
{
foreach (var item in element.Elements())
{
if (item.Name.LocalName == elementName)
{
return item.Attribute(attributeName).Value;
}
}
}
}
return null;
}
public static List<YouTubeInfo> LoadVideosKey(string keyWord, int start, int limit)
{
try
{
switch (search_based)
{
case 0: search = SEARCH; break;
case 1: search = Most_popular; break;
}
var xDoc = XmlReader.Create(string.Format(search, keyWord, start, limit));
SyndicationFeed feed = SyndicationFeed.Load(xDoc);
var links = (from item in feed.Items
select new YouTubeInfo
{
LinkUrl = item.Id,
Title = item.Title.Text,
EmbedUrl = item.Links.FirstOrDefault().Uri.AbsoluteUri,
ThumbNailUrl = GetAttributeFromGroup(item.ElementExtensions, "thumbnail", "url"),
Duration = int.Parse(GetAttributeFromGroup(item.ElementExtensions, "duration", "seconds") ?? "0"),
}).Take(limit);
return links.ToList<YouTubeInfo>();
}
catch (Exception e)
{
Trace.WriteLine(e.Message, "ERROR");
}
return null;
}
You can learn more about SyndicationFeed here
Your basic code is actually working fine. You did not post code for GetThumbnailUrlFromLink and for GetDuration, but I suspect you are having trouble with namespaces. See this answer for a sample of using namespaces.
Essentially, if you added:
static XNamespace nsMedia = "http://search.yahoo.com/mrss/";
static XNamespace nsYt = "http://gdata.youtube.com/schemas/2007";
then your Duration could look like:
Duration = (int)item.Element(nsMedia + "group").Element(nsYt + "duration").Attribute("seconds")
I have a list of contacts in XML file.
Each contact have a few properties and mdpr:connection in it.
Connection is separate object.
I read this list and get all contacts to a list with standard proeprties but how to map this Connection to object.
<?xml version="1.0" encoding="UTF-8"?>
<mdpr:Data xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mdpr="http://...">
<mdpr:contactList>
<mdpr:contact ID="{123456}" classID="Customer">
<mdpr:Name>data1</mdpr:Name>
<mdpr:TransportCode>data2</mdpr:TransportCode>
<mdpr:connection connectionIndex="0" fromID="{12345}" toID="{123456}">
<mdpr:status>1-5</mdpr:status>
<mdpr:startDate>2012-03-13T10:23:00Z</mdpr:startDate>
<mdpr:endDate>2013-03-13T13:44:00Z</mdpr:endDate>
</mdpr:connection>
</mdpr:contact>
</mdpr:contactList>
...
Classes:
public class Contact
{
public string Name { get; set; }
public string TransportCode { get; set; }
public Connection Connection { get; set; }
public TransportPlan()
{
this.Connection = new Connection();
}
}
public class Connection
{
public string status{ get; set; }
public string startDate{ get; set; }
public string endDate { get; set; }
}
Code to read data:
XNamespace mdpr = "http://...";
var contacts = from c in xdoc.Root.Element(mdpr + "contactList")
.Elements(mdpr + "contact")
select new Contact {
TransportCode = (string)c.Element(mdpr + "TransportCode"),
Name = (string)c.Element(mdpr + "Name")
};
So the question is how to read mdpr:connection?
You can access the elements directly by adding another '.Element'. I added a variable for better readability.
var contacts = from c in xdoc.Element(mdpr + "Data")
.Element(mdpr + "contactList")
.Elements(mdpr + "contact")
let contact = c
let connection = contact.Element(mdpr + "connection")
select new Contact
{
TransportCode = (string)contact.Element(mdpr + "TransportCode"),
Name = (string)contact.Element(mdpr + "Name"),
Connection = new Connection
{
status = (string)connection.Element(mdpr + "status"),
startDate = (string) connection.Element(mdpr + "startDate"),
endDate = (string)connection.Element(mdpr + "endDate"),
},
};
If you want to allow multiple connections (in order to make the scenario more complex)
public class Contact
{
public string Name { get; set; }
public string TransportCode { get; set; }
public List<Connection> Connections { get; set; }
}
Code to parse multiple connections
var contacts = from c in xdoc.Element(mdpr + "Data")
.Element(mdpr + "contactList")
.Elements(mdpr + "contact")
let contact = c
let connections = contact.Elements(mdpr + "connection")
select new Contact
{
TransportCode = (string)contact.Element(mdpr + "TransportCode"),
Name = (string)contact.Element(mdpr + "Name"),
Connections = connections.Select( connection =>
new Connection
{
status = (string)connection.Element(mdpr + "status"),
startDate = (string) connection.Element(mdpr + "startDate"),
endDate = (string)connection.Element(mdpr + "endDate"),
}).ToList(),
};