Hello in a Windows Phone 8 app I have run into a problem, with deserializing xml from a webclient download.. I wait on the DownloadStringCompletedEvent and then I use the folowing code.
private void PopularDownloaded(object sender, DownloadStringCompletedEventArgs e)
{
if (e.Result == null || e.Error != null)
{
MessageBox.Show("There was an error connecting to the server");
}
else
{
//MessageBox.Show(e.Result.ToString());
XDocument loadedpopData = XDocument.Load(e.Result);
var popdata = from query in loadedpopData.Descendants("pattern")
select new poppatterns
{
Title = (string)query.Element("title"),
UserName = (string)query.Element("userName"),
DateCreated = (string)query.Element("dateCreated"),
ImageUrl = (string)query.Element("imageUrl"),
ApiUrl = (string)query.Element("apiUrl"),
};
poplonglist.ItemsSource = popdata.ToList();
}
}
but it throws the following exception:
An unhandled exception of type 'System.Reflection.TargetInvocationException' occurred in System.Windows.ni.dll
If I but a local xml file in the project and then load that like this
XDocument loadedpopData = XDocument.Load("Resources/top.xml");
it loads fine so it must be something with the
XDocument loadedpopData = XDocument.Load(e.Result);
I tried looking at the e.Result and it is the correct data.
Any ideas what I'm doing wrong??
In e.Result you have an XML string, but XDocument.Load(string) is for load data from file, and string argument is path to file, you should use XDocument.Parse(e.Result) to load XDocument from XML string data.
Post in MSDN about Load: XDocument.Load()
Post in MSDN about Parse: XDocument.Parse()
Change this line
//MessageBox.Show(e.Result.ToString());
XDocument loadedpopData = XDocument.Load(e.Result);
to
//MessageBox.Show(e.Result.ToString());
XDocument loadedpopData = XDocument.Parse(e.Result);
quick cooking sample. and result as well, from LinqPad
code:
var xml = new XElement("root");
for (var i = 0; i <10; i++)
{
xml.Add(new XElement("pattern", new XElement("title", "title" + i.ToString()),
new XElement("title", "title" + i.ToString()),
new XElement("userName", "userName" + i.ToString()),
new XElement("dateCreated", "dateCreated" + i.ToString()),
new XElement("imageUrl", "ImageUrl" + i.ToString()),
new XElement("apiUrl", "ApiUrl" + i.ToString())));
}
var xmlString = xml.ToString();
var loadedpopData = XDocument.Parse(xmlString);
var popdata = from query in loadedpopData.Descendants("pattern")
select new {
Title = (string)query.Element("title"),
UserName = (string)query.Element("userName"),
DateCreated = (string)query.Element("dateCreated"),
ImageUrl = (string)query.Element("imageUrl"),
ApiUrl = (string)query.Element("apiUrl"),
};
popdata.Dump();
Result:
Title UserName DateCreated ImageUrl ApiUrl
title0 userName0 dateCreated0 ImageUrl0 ApiUrl0
title1 userName1 dateCreated1 ImageUrl1 ApiUrl1
title2 userName2 dateCreated2 ImageUrl2 ApiUrl2
title3 userName3 dateCreated3 ImageUrl3 ApiUrl3
title4 userName4 dateCreated4 ImageUrl4 ApiUrl4
title5 userName5 dateCreated5 ImageUrl5 ApiUrl5
title6 userName6 dateCreated6 ImageUrl6 ApiUrl6
title7 userName7 dateCreated7 ImageUrl7 ApiUrl7
title8 userName8 dateCreated8 ImageUrl8 ApiUrl8
title9 userName9 dateCreated9 ImageUrl9 ApiUrl9
Related
I already wrote a code to deserialize an xml file with root element and elemnts only, the problem that i need it to deserialize a XML file that contains root element, elements and CHILD element.
The file looks like this:
<Claim>
<ClaimNo>LL0000110262</ClaimNo>
<PolicyNo>LP0000004481</PolicyNo>
<PolicyHolder>EST Boras AB</PolicyHolder>
<Locations>
<Location>
<AddressId>1</AddressId>
<Address1>Example Street 1</Address1>
<Addresstype>LocationOfLoss</Addresstype>
<City>Helsinki</City>
<Country>FI</Country>
<Postalzone>12345</Postalzone>
</Location>
</Locations>
<UWYear>2015</UWYear>
<PeriodStart>2015-01-01</PeriodStart>
<PeriodEnd>2015-12-31</PeriodEnd>
<DateOfLoss>2015-07-15</DateOfLoss>
<ReportDate></ReportDate>
<StatusAsPer>2015-12-31</StatusAsPer>
<Coverage>?</Coverage>
<TypeOfLoss>Leakage</TypeOfLoss>
<OriginalCurrency>EUR</OriginalCurrency>
<PaymentCurrency>EUR</PaymentCurrency>
<TotalReservesOrigCurr>0.00</TotalReservesOrigCurr>
<TotalPaymentOrigCurr>0.00</TotalPaymentOrigCurr>
<DeductibleOrigCurr>85000.00</DeductibleOrigCurr>
<TotalAmountOfClaimOrigCurr>3680.00</TotalAmountOfClaimOrigCurr>
<Status>Active</Status>
While my method looks like this:
public async Task<IActionResult> XmlPage(IFormFile xmlFile)
{
var uploads = hostingEnvironment.WebRootPath;
var filePath = Path.Combine(uploads, xmlFile.FileName).ToString();
if (xmlFile.ContentType.Equals("application/xml") || xmlFile.ContentType.Equals("text/xml"))
{
try
{
using (var fileStream = new FileStream(filePath, FileMode.Create))
{
await xmlFile.CopyToAsync(fileStream);
fileStream.Dispose();
XDocument xDoc = XDocument.Load(filePath);
List<DmgRegisterVM> dmgRegistterList = GetDmgFromXml(xDoc);
context.SaveXmlToDb(dmgRegistterList);
}
}
// returning at httpGet with a temp message that says att uploadin is failed
catch
{
ViewBag.Error = "Converting fail";
}
}
// returning at httpGet with a temp message that says att uploadin is failed
else
{
ViewBag.Error = "Uploading fail";
}
return View("Index");
}
private List<DmgRegisterVM> GetDmgFromXml(XDocument xDoc)
{
var list = xDoc.Descendants("Claim").Select(dmgReg =>
new DmgRegisterVM
{
Uwyear = dmgReg.Element("UWYear").Value,
ClaimNo = dmgReg.Element("ClaimNo").Value,
PolicyNo = dmgReg.Element("PolicyNo").Value,
PolicyName = dmgReg.Element("PolicyHolder").Value,
Address1 = dmgReg.Element("Address1").Value,
Address2 = dmgReg.Element("Addresstype").Value,
PostalLocation = dmgReg.Element("City").Value,
Country = dmgReg.Element("Country").Value,
PostalCode = dmgReg.Element("Postalzone").Value
}).ToList();
return list;
}
The question is how do get this child elemnt into my list (deserialized)
<Locations>
<Location>
<AddressId>1</AddressId>
<Address1>Example Street 1</Address1>
<Addresstype>LocationOfLoss</Addresstype>
<City>Helsinki</City>
<Country>FI</Country>
<Postalzone>12345</Postalzone>
</Location>
</Locations>
Assuming you know there will only be one location, then you can do something like this:
var viewModels =
from claim in doc.Descendants("Claim")
from location in claim.Descendants("Location")
select new DmgRegisterVM
{
Uwyear = (string) claim.Element("UWYear"),
ClaimNo = (string) claim.Element("ClaimNo"),
PolicyNo = (string) claim.Element("PolicyNo"),
PolicyName = (string) claim.Element("PolicyHolder"),
Address1 = (string) location.Element("Address1"),
Address2 = (string) location.Element("Addresstype"),
PostalLocation = (string) location.Element("City"),
Country = (string) location.Element("Country"),
PostalCode = (string) location.Element("Postalzone")
};
I am trying to make a database, but i need to get info from a website. Mainly the Title, Date, Length and Genre from the IMDB website. I have tried like 50 different things and it is just not working.
Here is my code.
public string GetName(string URL)
{
HtmlWeb web = new HtmlWeb();
HtmlDocument doc = web.Load(URL);
var Attr = doc.DocumentNode.SelectNodes("//*[#id=\"overview - top\"]/h1/span[1]#itemprop")[0];
return Name;
}
When I run this it just gives me a XPathException. I just want it to return the Title of a movie. I am now just using this movie for a example and testing but, I want it to work with all movies http://www.imdb.com/title/tt0405422
I am using the HtmlAgilityPack.
The last bit of your XPath is not valid. Also to get only single element from HtmlDocument() you can use SelectSingleNode() instead of SelectNodes() :
HtmlWeb web = new HtmlWeb();
HtmlDocument doc = web.Load("http://www.imdb.com/title/tt0405422/");
var xpath = "//*[#id='overview-top']/h1/span[#class='itemprop']";
var span = doc.DocumentNode.SelectSingleNode(xpath);
var title = span.InnerText;
Console.WriteLine(title);
output :
The 40-Year-Old Virgin
demo link : *
https://dotnetfiddle.net/P7U5A7
*) the demo shows that the correct title is printed, along with an error specific to .NET Fiddle (you can safely ignore the error).
I making something familiar and this is my code which gets info from imdb.com website.:
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");
}
//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;
}
Maybe you will find something useful
I have a XML loaded from a URL like this:
WebClient client = new WebClient();
client.Encoding = Encoding.UTF8;
try
{
string reply = client.DownloadString("http://Example.com/somefile.xml");
label1.Text = reply;
}
catch
{
label1.Text = "FAILED";
}
That XML belongs to a RSS Feed. I want that label1.Text shows just the titles of that XML. How can I achieve that?
Example of label1.Text
This is my first title - This is my 2nd title - And this is my last title
You can load your XML into an XmlDocument and then use XPath to Get the value of each node you're targeting.
XmlDocument doc = new XmlDocument();
doc.LoadXml(reply);
XmlNodeList nodes = doc.SelectNodes("//NodeToSelect");
foreach (XmlNode node in nodes)
{
//If the value you want is the content of the node
label1.Text = node.InnerText;
//If the value you want is an attribute of the node
label1.Text = node.Attributes["AttibuteName"].Value;
}
If you are not familiar with XPath you can always check here :
http://www.w3schools.com/xpath/xpath_syntax.asp
var xml= XElement.Parse(reply);
label1.Text = string.Join(Environment.NewLine, xml
.Descendants()
.Where (x => !string.IsNullOrEmpty(x.Value))
.Select(x=> string.Format("{0}: {1}", x.Name, x.Value))
.ToArray());
You probably need to parse the RSS XML manually to get the title. Here is some sample code for your reference:
private static List<FeedsItem> ParseFeeds(string feedsXml)
{
XDocument xDoc = XDocument.Parse(feedsXml);
XNamespace xmlns = "http://www.w3.org/2005/Atom";
var items = from entry in xDoc.Descendants(xmlns + "entry")
select new FeedsItem
{
Id = (string)entry.Element(xmlns + "id").Value,
Title = (string)entry.Element(xmlns + "title").Value,
AlternateLink = (string)entry.Descendants(xmlns + "link").Where(link => link.Attribute("rel").Value == "alternate").First().Attribute("href").Value
};
Console.WriteLine("Count = {0}", items.Count());
foreach(var i in items)
{
Console.WriteLine(i);
}
return null;
}
I am parsing an xml file using the following which works well but my question is how do I get the value from the tag <themename> because I am using oXmlNodeList for my loop. Just don't want to be writing a separate routine for one tag.
XmlDocument xDoc = new XmlDocument();
List<active_theme> listActiveTheme = new List<active_theme>();
string path = AppDomain.CurrentDomain.BaseDirectory + #"themes\test\configuration.xml";
xDoc.Load(AppDomain.CurrentDomain.BaseDirectory + #"themes\test\configuration.xml");
//select a list of Nodes matching xpath expression
XmlNodeList oXmlNodeList = xDoc.SelectNodes("configuration/masterpages/masterpage");
Guid newGuid = Guid.NewGuid();
foreach (XmlNode x in oXmlNodeList)
{
active_theme activetheme = new active_theme();
string themepage = x.Attributes["page"].Value;
string masterpage = x.Attributes["name"].Value;
activetheme.active_theme_id = newGuid;
activetheme.theme = "Dark";
activetheme.page = themepage;
portalContext.AddToActiveTheme(activetheme);
}
portalContext.SaveChanges();
XML File for theme configuration
<configuration>
<themename>Dark Theme</themename>
<masterpages>
<masterpage page="Contact" name="default.master"></masterpage>
<masterpage page="Default" name="default.master"></masterpage>
<masterpage page="Blue" name="blue.master"></masterpage>
<masterpage page="red" name="red.master"></masterpage>
</masterpages>
</configuration>
I'd use LINQ to XML to start with. Something like this:
var doc = XDocument.Load(...);
var themeName = doc.Root.Element("themename").Value;
Guid themeGuid = Guid.NewGuid();
foreach (var element in doc.Root.Element("masterpages").Elements("masterpage"))
{
ActiveTheme theme = new ActiveTheme
{
ThemeName = themeName,
ActiveThemeId = themeGuid,
Page = element.Attribute("page").Value,
MasterPage = element.Attribute("name").Value
};
portalContent.AddToActiveTheme(theme);
}
portalContext.SaveChanges();
I have a problem, I am trying to list all my tfs projects and I am having this exception:
Value does not fall within the expected range.
Here is my method
public async Task<XElement> Deserialize()
{
string xml = "https://tfsodata.visualstudio.com/DefaultCollection/Projects('xxxx')/WorkItems";
var feed = await this.GetAsync(PROJECTS_PATH);
var x = feed.Items.ToString();
XElement dataTfs = new XElement(x);
foreach(var tfsdata in feed.Items)
{
var xDoc = XDocument.Parse(tfsdata.Content.Text);
IEnumerable<XElement> elem = xDoc.Elements();
XNamespace m = "http://schemas.microsoft.com/ado/2007/08/dataservices/metadata";
XNamespace d = "http://schemas.microsoft.com/ado/2007/08/dataservices";
var data = from query in xDoc.Descendants(m + "properties")
select new TfsEntities.Models.TfsEntities.properties
{
Title = (string)query.Element(d + "Title"),
State = (string)query.Element(d + "State"),
Reason = (string)query.Element(d + "Reason")
};
dataTfs.Add(data.ToList());
}
return (XElement)dataTfs;
}
Does anyone know how to fix this problem please?
Thank you