I have these 2 methods wrote in another class, but how can I reach the output off this from other classes? I wan't just the value of lsTags.
That's my code:
private void LoadXMLFile()
{
WebClient xmlClient = new WebClient();
xmlClient.DownloadStringCompleted += new DownloadStringCompletedEventHandler(XMLFileLoaded);
xmlClient.DownloadStringAsync(new Uri("codeFragments.xml", UriKind.RelativeOrAbsolute));
}
private void XMLFileLoaded(object sender, DownloadStringCompletedEventArgs e)
{
if (e.Error == null)
{
string xmlData = e.Result;
XDocument xDoc = XDocument.Parse(xmlData);
var tagsXml = from c in xDoc.Descendants("Tag") select c.Attribute("name");
foreach (string tagName in tagsXml)
{
Tag oTag = new Tag();
oTag.name = tagName;
var tags = from d in xDoc.Descendants("Tag")
where d.Attribute("name").Value == tagName
select d.Elements("oFragments");
var tagXml = tags.ToArray()[0];
foreach (var tag in tagXml)
{
CodeFragments oFragments = new CodeFragments();
oFragments.tagURL = tag.Attribute("tagURL").Value;
//Tags.tags.Add(oFragments);
oTag.lsTags.Add(oFragments);
}
this.lsTags.Add(oTag);
}
}
}
Silverlight does not support XmlDocument. Use LINQ to XML instead.
Related
Now I have code which is sync, I need to make it async.
I tried what Visual Studio 2012 offers, the code have no mistackes but with no result.
Please help.
Code:
protected void Page_Load(object sender, EventArgs e)
{
this.PopulateAtomFeed1();
this.PopulateAtomFeed2();
this.PopulateAtomFeed3();
this.PopulateAtomFeed4();
}
private void PopulateAtomFeed1()
{
string RssFeedUrl = "http://www.faktor.mk/feed/ekonomija/";
List<Feeds> feeds = new List<Feeds>();
try
{
XDocument xDoc = new XDocument();
xDoc = XDocument.Load(RssFeedUrl);
var items = (from x in xDoc.Descendants("item").Take(10)
select new
{
title = x.Element("title").Value,
link = x.Element("link").Value,
pubDate = x.Element("pubDate").Value,
description = x.Element("description").Value
});
if (items != null)
{
foreach (var i in items)
{
Feeds f = new Feeds
{
Title = i.title,
Link = i.link,
PublishDate = i.pubDate,
Description = i.description
};
feeds.Add(f);
}
}
gvRss1.DataSource = feeds;
gvRss1.DataBind();
}
catch (Exception ex)
{
feeds = null;
}
}
I get an error "The name 'xDocument' does not exist in the current context" when writing some code for RSS feed reader. What is wrong here with xDocument?
Here is my code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Xml.Linq;
namespace RSSreaderAPP
{
public partial class _Default : Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
ReadRss();
}
}
private void ReadRss()
{
string RssFeedUrl = "http://feeds.feedburner.com/neowin-main";
List<Feeds> feeds = new List<Feeds>();
try
{
XDocument xDoc = new XDocument();
xDoc = xDocument.Load(RssFeedUrl);
var items = (from x in xDoc.Descendants("item")
select new
{
title = x.Element("title").Value,
link = x.Element("link").Value,
pubDate = x.Element("publish date").Value,
description = x.Element("description").Value
});
if (items != null)
{
foreach (var i in items)
{
Feeds f = new Feeds
{
Title = i.title,
Link = i.link,
PublishDate = i.pubDate,
Description = i.description
};
feeds.Add(f);
}
}
gridViewRSS.DataSource = feeds;
gridViewRSS.DataBind();
}
catch (Exception ex)
{
throw;
}
}
}
}
This is to avoid annoying message.
I changed
XDocument xDoc = new XDocument();
xDoc = xDocument.Load(RssFeedUrl);
to
XDocument xDoc = XDocument.Load(RssFeedUrl);
and also pubDate = x.Element("publish date").Value,
to
pubDate = x.Element("pubDate").Value,
private void ReadRss()
{
string RssFeedUrl = "http://feeds.feedburner.com/neowin-main";
List<Feeds> feeds = new List<Feeds>();
try
{
//XDocument xDoc = new XDocument();
//xDoc = xDocument.Load(RssFeedUrl);
XDocument xDoc = XDocument.Load(RssFeedUrl);
var items = (from x in xDoc.Descendants("item")
select new
{
title = x.Element("title").Value,
link = x.Element("link").Value,
pubDate = x.Element("pubDate").Value,
description = x.Element("description").Value,
});
if (items != null)
{
foreach (var i in items)
{
Feeds f = new Feeds
{
Title = i.title,
Link = i.link,
PublishDate = i.pubDate,
Description = i.description,
};
feeds.Add(f);
}
}
gridViewRSS.DataSource = feeds;
gridViewRSS.DataBind();
}
catch (Exception ex)
{
throw;
}
}
I have the following code:
static void Main(string[] args)
{
XmlDocument xml = new XmlDocument();
xml.Load(#"C:\MR.xml");
XmlNodeList stations = xml.SelectNodes("//FileDump/Message/Attachment");
var Message_ID = xml.SelectSingleNode("//FileDump/Message/MsgID").InnerXml;
Console.WriteLine("Message ID is :{0}", Message_ID);
foreach (XmlNode station in stations)
{
var File_Name = station.SelectSingleNode("FileName").InnerXml;
var File_ID = station.SelectSingleNode("FileID").InnerXml;
}
}
FileID and FileName do not always exist in some files. How can I avoid NullReferenceExceptions in this case?
I would try to something like this if that check has to happen in lot of places and to keep the code simple and clear
public static class Helpers
{
public static string GetInnerXml(this XmlNode node, string innerNodeName)
{
string innerXml = "";
XmlNode innerNode = node.SelectSingleNode(innerNodeName);
if (innerNode != null)
{
innerXml = innerNode.InnerXml;
}
return innerXml;
}
}
and use it like this
static void Main(string[] args)
{
XmlDocument xml = new XmlDocument();
xml.Load(#"C:\MR.xml");
XmlNodeList stations = xml.SelectNodes("//FileDump/Message/Attachment");
var Message_ID = xml.GetInnerXml("//FileDump/Message/MsgID");
Console.WriteLine("Message ID is :{0}", Message_ID);
foreach (XmlNode station in stations)
{
var File_Name = station.GetInnerXml("FileName");
var File_ID = station.GetInnerXml("FileID");
}
}
You could do something like:
string FileName= "";
string File_ID = "";
if (station.SelectSingleNode("FileName") != null)
File_Name = station.SelectSingleNode("FileName").InnerXml;
if (station.SelectSingleNode("FileID") != null)
File_ID = station.SelectSingleNode("FileID").InnerXml;
And continue processing if the vars are not the empty string ... ("") ...
static void Main(string[] args)
{
XmlDocument xml = new XmlDocument();
xml.Load(#"C:\MR.xml");
XmlNodeList stations = xml.SelectNodes("//FileDump/Message/Attachment");
var Message_ID = xml.SelectSingleNode("//FileDump/Message/MsgID").InnerXml;
Console.WriteLine("Message ID is :{0}", Message_ID);
foreach (XmlNode station in stations)
{
var fileNameNode = station.SelectSingleNode("FileName");
var fileIdNode = station.SelectSingleNode("FileID");
var File_Name = fileNameNode == null ? (string)null : fileNameNode.InnerXml;
var File_ID = fileIdNode == null ? (string)null : fileIdNode.InnerXml;;
}
}
I usually use extension methods for handling unexpected nulls.
public static string GetValueIfNotNull(this XmlAttribute xmlAttribute)
{
if (xmlAttribute == null)
{
return null;
}
return xmlAttribute.Value;
}
Then I can do myElement.Attribute("someAttribute").GetValueIfNotNull();
I recursively want to display xml nodes. But unfortunately it doesn't work. The output is only the first element of the xml file. Why?
public string GetOutline(int indentLevel, XmlNode xnod)
{
StringBuilder result = new StringBuilder();
XmlNode xnodWorking;
result = result.AppendLine(new string('-', indentLevel * 2) + xnod.Name);
if (xnod.NodeType == XmlNodeType.Element)
{
if (xnod.HasChildNodes)
{
xnodWorking = xnod.FirstChild;
while (xnodWorking != null)
{
GetOutline(indentLevel + 1, xnodWorking);
xnodWorking = xnodWorking.NextSibling;
}
}
}
return result.ToString();
}
Here the code calling the function. The XML file begins with <Videos> then <Video>... etc...
private void button2_Click(object sender, EventArgs e)
{
SaveFileDialog fDialog = new SaveFileDialog();
fDialog.Title = "Save XML File";
fDialog.FileName = "drzewo.xml";
fDialog.CheckFileExists = false;
fDialog.InitialDirectory = #"C:\Users\Piotrek\Desktop";
if (fDialog.ShowDialog() == DialogResult.OK)
{
using (var newXmlFile = File.Create(fDialog.FileName));
{
string xmlTree = fDialog.FileName.ToString();
XmlDocument xdoc = new XmlDocument();
xdoc.Load(XML);
XmlNode xnodDE = xdoc.DocumentElement;
textBox2.Text = GetOutline(0, xnodDE);
//StringBuilder result = new StringBuilder();
/*
foreach (var childelement in xdoc.DescendantNodes().OfType<XElement>()
.Select(x => x.Name).Distinct())
{
result.Append(childelement + Environment.NewLine );
}
textBox2.Text = result.ToString();
*/
using (StreamWriter sw = File.AppendText(xmlTree))
{
sw.Write(textBox2.Text);
}
}
}
XML content :
<Videos>
<Video>
<Title>The Distinguished Gentleman</Title>
<Director>Jonathan Lynn</Director>
<Actors>
<Actor>Eddie Murphy</Actor>
<Actor>Lane Smith</Actor>
<Actor>Sheryl Lee Ralph</Actor>
<Actor>Joe Don Baker</Actor>
</Actors>
<Length>112 Minutes</Length>
<Format>DVD</Format>
<Rating>R</Rating>
</Video>
<Video>
<Title>Her Alibi</Title>
<Director>Bruce Beresford</Director>
<Length>94 Mins</Length>
<Format>DVD</Format>
<Rating>PG-13</Rating>
</Video>
</Videos>
You need to read all document line by line whith a for each or a while instruction
XmlReader reader = XmlReader.Create(your xml file);
reader.MoveToContent();
while (reader.Read())
{
// your code
}
reader.Close();
not the best way, try to have a look also on linq to xml
try that
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
namespace testStackOverflow
{
class Program
{
static void Main(string[] args)
{
//Load xml
XDocument xdoc = XDocument.Load("test.xml");
//Run query
var lv1s = from lv1 in xdoc.Descendants("Video")
select new
{
title = lv1.Element("Title").Value
};
//Loop through results
foreach (var lv1 in lv1s)
{
Console.WriteLine(lv1.title);
}
Console.ReadLine();
}
}
}
You're not doing anything to add the results of the recursive calls to the string you're building. You need to do this:
result.Append(GetOutline(indentLevel + 1, xnodWorking));
And this modification should avoid the text nodes and nodes with the same name:
public string GetOutline(int indentLevel, XmlNode xnod)
{
StringBuilder result = new StringBuilder();
XmlNode xnodWorking;
result = result.AppendLine(new string('-', indentLevel * 2) + xnod.Name);
if (xnod.HasChildNodes)
{
List<string> foundElements = new List<string>();
xnodWorking = xnod.FirstChild;
while (xnodWorking != null)
{
if(xnodworking.NodeType == XmlNodeType.Element && !foundElements.Contains(xnodworking.Name))
{
result.Append(GetOutline(indentLevel + 1, xnodWorking));
foundElements.Add(xnodworking.Name);
}
xnodWorking = xnodWorking.NextSibling;
}
}
return result.ToString();
}
I've been struggling for the past 3 days with removing or overwriting ListPicker values. I want the click event of a button to remove the old list items and populate it with the new ones. I use LINQ to parse values from an XML file. The problem is that no matter what I try I always get an exception such as "Operation not supported on read-only collection." etc. Is there a way to remove all the values from the ListPicker?
Here's the code:
public partial class Visa : PhoneApplicationPage
{
List<Tiedot> vastausLista = new List<Tiedot>();
XDocument lista = XDocument.Load("Faktat.xml");
Random rand = new Random();
int piste = 0;
int levelStart = 1;
string level = string.Empty;
// Constructor
public Visa()
{
InitializeComponent();
tbPisteet.Text = string.Format("{0}/25", piste.ToString());
level = string.Format("level{0}", levelStart.ToString());
}
protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
if (levelStart <= 1)
{
var documents =
(from docs in lista.Descendants("Taso")
where docs.Attribute("id").Value == level
select new
{
Elain = docs.Elements("vaihtoehto")
}).ToList();
foreach (var doc in documents)
{
foreach (var section in doc.Elain)
{
foreach (var item in section.Elements("vastaus"))
{
vastausLista.Add(new Tiedot { Elain = item.Value });
}
}
}
vaihtoehtoLista.ItemsSource = vastausLista;
var kuvaKysymys = (from tiedot in lista.Descendants("Taso")
where tiedot.Attribute("id").Value == level
select new Tiedot
{
Kuva = (string)tiedot.Element("kuva").Value,
Question = (string)tiedot.Element("kysymys").Value
}).FirstOrDefault();
BitmapImage kuvaKuva = new BitmapImage();
kuvaKuva.UriSource = new Uri(kuvaKysymys.Kuva, UriKind.Relative);
image.Source = kuvaKuva;
tbQuestion.Text = kuvaKysymys.Question;
}
base.OnNavigatedTo(e);
}
private void vaihtoehtoLista_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (vaihtoehtoLista.SelectedIndex == 1)
{
Update();
}
}
private void button1_Click(object sender, RoutedEventArgs e)
{
UpdateLevel();
}
public void Update()
{
piste++;
tbPisteet.Text = string.Format("{0}/25", piste.ToString());
MessageBox.Show("You're correct!!");
}
public void RemoveOldLevel()
{
while (vastausLista.Count > 0)
vaihtoehtoLista.Items.Remove(vastausLista[0]);
}
public void UpdateLevel()
{
levelStart++;
level = string.Format("level{0}", levelStart.ToString());
var documents =
(from docs in lista.Descendants("Taso")
where docs.Attribute("id").Value == level
select new
{
Elain = docs.Elements("vaihtoehto")
}).ToList();
foreach (var doc in documents)
{
foreach (var section in doc.Elain)
{
foreach (var item in section.Elements("vastaus"))
{
vastausLista.Add(new Tiedot { Elain = item.Value });
}
}
}
RemoveOldLevel();
vaihtoehtoLista.ItemsSource = vastausLista;
var kuvaKysymys = (from tiedot in lista.Descendants("Taso")
where tiedot.Attribute("id").Value == level
select new Tiedot
{
Kuva = (string)tiedot.Element("kuva").Value,
Question = (string)tiedot.Element("kysymys").Value
}).FirstOrDefault();
BitmapImage kuvaKuva = new BitmapImage();
kuvaKuva.UriSource = new Uri(kuvaKysymys.Kuva, UriKind.Relative);
image.Source = kuvaKuva;
tbQuestion.Text = kuvaKysymys.Question;
}
}
You have to use an ObservableCollection with your elements inside, as the DataContext of your ListPicker. Something like this:
ListPicker picker = new ListPicker();
ObservableCollection<Object> coll = your items inside;
picker.DataContext = coll;
And after you can modify directly the ObservableCollection. Or you can use:
ListPicker picker = new ListPicker();
picker.ItemsSource = List<> with your items;
But you have to reset the ItemSource each time you change the content of your List<>.