Writing online XML file to textbox - c#

I am using a PHP script to generate xml files. I want to write the data in the XML file to a Textblock in my Windows Phone 8 App.
When I debug, I get an error which is not caught my the catch. A print screen of the error: http://i811.photobucket.com/albums/zz38/JelleK1996/errorxml1_zps20df0a45.png
What is wrong?
This is my code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Navigation;
using Microsoft.Phone.Controls;
using Microsoft.Phone.Shell;
using System.Xml;
using System.IO;
using System.Xml.Linq;
using System.Diagnostics;
namespace xml1
{
public partial class MainPage : PhoneApplicationPage
{
// Constructor
public MainPage()
{
InitializeComponent();
// Sample code to localize the ApplicationBar
//BuildLocalizedApplicationBar();
}
protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
try
{
HttpWebRequest request = WebRequest.Create("http://cocktailpws.net23.net/requests/get_cocktail.php?id=10") as HttpWebRequest;
request.BeginGetResponse(r =>
{
var reponse = request.EndGetResponse(r);
//XDocument xmlDoc = XDocument.Load(reponse.GetResponseStream());
XmlReader reader = XmlReader.Create(reponse.GetResponseStream());
while (reader.Read())
{
switch (reader.NodeType)
{
case XmlNodeType.Element: // Het knooppunt is een element.
Console.Write("<" + reader.Name);
Console.WriteLine(">");
break;
case XmlNodeType.Text: //De tekst in elk element weergeven.
tb1.Text = tb1.Text + reader.Value + "\r\n";
Console.WriteLine(reader.Value);
break;
case XmlNodeType.EndElement: //Het einde van het element weergeven.
Console.Write("</" + reader.Name);
Console.WriteLine(">");
break;
}
}
}, null);
}
catch (Exception myExc)
{
Console.WriteLine(myExc.Message);
}
}
}
}

Firstly you have not got try catch block inside lambda function. Thats why you cant handle error
Secondly how to solve:
change :
tb1.Text = tb1.Text + reader.Value + "\r\n";
to
Dispatcher.BeginInvoke(() => {
tb1.Text = tb1.Text + reader.Value + "\r\n";
});
Thirdly,
I Believe you need rewrite your xml loop, Cause your code is inefficent way. It will call text change if there are many texts.So build string then after loop call text change
StringBuilder res = new StringBuilder();
...
//inside xml loop:
res.AppendLine(reader.Value);
...
//after loop:
Dispatcher.BeginInvoke(() => {
tb1.Text = res.ToString();
});
And check this to see what was error. or search invalid thread call
invalid thread call

I believe you must access tb1 from the UI thread, so I would suggest trying to use a statement similar to this:
case XmlNodeType.Text: //De tekst in elk element weergeven.
{
tb1.Dispatcher.BeginInvoke(() =>
{
tb1.Text = tb1.Text + reader.Value + "\r\n";
});
Console.WriteLine(reader.Value);
}
break;

Related

"The given path's format is not supported" Error when trying to pull XML into Treeview

Currently trying to get a XML file from a location on my machine to display to my Treeview. I pretty much used the code from another stackoverflow question:
Recursion, parsing xml file with attributes into treeview c#
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Xml;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
string Path = Application.StartupPath + #"C:\Users\apearson\Documents\Works.xml";
public Form1()
{
InitializeComponent();
DisplayTreeView(Path);
}
private void DisplayTreeView(string pathName)
{
try
{
XmlDocument dom = new XmlDocument();
dom.Load(pathName);
treeView1.Nodes.Clear();
foreach (XmlNode xNode in dom.ChildNodes)
{
var tNode = treeView1.Nodes[treeView1.Nodes.Add(new TreeNode(xNode.Name))];
AddNode(xNode, tNode);
}
}
catch (XmlException xmlEx)
{
MessageBox.Show(xmlEx.Message);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
private void AddNode(XmlNode inXmlNode, TreeNode inTreeNode)
{
if (inXmlNode is XmlElement)
{
foreach (var att in inXmlNode.Attributes.Cast<XmlAttribute>().Where(a => !a.IsDefaultNamespaceDeclaration()))
{
inTreeNode.Text = inTreeNode.Text + " " + att.Name + ": " + att.Value;
}
var nodeList = inXmlNode.ChildNodes;
foreach (XmlNode xNode in inXmlNode.ChildNodes)
{
var tNode = inTreeNode.Nodes[inTreeNode.Nodes.Add(new TreeNode(xNode.Name))];
AddNode(xNode, tNode);
}
}
else
{
inTreeNode.Text = (inXmlNode.OuterXml).Trim();
}
treeView1.ExpandAll();
}
}
When debugging, I noticed that it will stop at the dom.Load(pathName) then go straight to the catch. Then throw me the error of "The given path's format is not supported". I've seen some other articles with this issue but nothing with a Treeview so don't know if they would have been much help. Is there something I'm missing?
This part
string Path = Application.StartupPath + #"C:\Users\apearson\Documents\Works.xml
... will concatenate the startup path with the full path you define as literal.
This will lead to something like
C:\blah\blub\C:\Users\apearson\Documents\Works.xml
...which is not a valid path..

Get Xml Data From URL

How can I get a list of items straight from the xml file that is on the host?
More precisely, I want to This xml file http://gamerpro.webd.pl/data/modlist.xml I pulled out a list of items and listened to the code
If (! File.Exists ("received list of items"))
{
Await client.DownloadFileTaskAsync (new Uri (url + "received item list"), dir + "received item list");
}
using System;
using System.Xml;
namespace ReadXMLfromURL
{
/// <summary>
/// Summary description for Class1.
/// </summary>
class Class1
{
static void Main(string[] args)
{
String URLString = "http://localhost/books.xml";
XmlTextReader reader = new XmlTextReader (URLString);
while (reader.Read())
{
switch (reader.NodeType)
{
case XmlNodeType.Element: // The node is an element.
Console.Write("<" + reader.Name);
while (reader.MoveToNextAttribute()) // Read the attributes.
Console.Write(" " + reader.Name + "='" + reader.Value + "'");
Console.Write(">");
Console.WriteLine(">");
break;
case XmlNodeType.Text: //Display the text in each element.
Console.WriteLine (reader.Value);
break;
case XmlNodeType. EndElement: //Display the end of the element.
Console.Write("</" + reader.Name);
Console.WriteLine(">");
break;
}
}
}
}
}
You could do something like this
// Make your request
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, requestURL);
request.Headers.Add("Accept", "application/xml");
HttpResponseMessage response = client.SendAsync(request).Result;
// Parse your response
if (response.IsSuccessStatusCode)
{
using (Stream httpResponseStream = response.Content.ReadAsStreamAsync().Result)
{
XDocument responseXML = XDocument.Load(httpResponseStream);
// My Chosen element is the element you're looking for
IEnumerable<XElement> myElements = responseXML.Root.Elements("MyChosenElement");
foreach (XElement myEl in myElements)
{
// Access each element like this myEl.Child
// Do what you'd like with it
}
}
}

Printing multiple lines in a text box/block .net c#

So what I'm trying to do is print outputs to a textbox but what's happening is it's always using the last textbox2.text it finds because I assume that each time I print it out it overrides the last output. I'm looking for some sort of work around
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Web;
using System.Net;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
namespace ProgrammingProject
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void btn_getinfo_Click(object sender, RoutedEventArgs e)
{
string UserInput = "76561198056932916";
// string UserInput = textBox.Text;
ProfileSummary(UserInput);
}
public void ProfileSummary(string SteamID)
{
string SteamKey = "CensoredAPIKEY";
WebClient c = new WebClient();
var data = c.DownloadString("http://api.steampowered.com/ISteamUser/GetPlayerSummaries/v0002/" + "?key=" + SteamKey + "&steamids=" + SteamID);
//Console.WriteLine(data);
JObject o = JObject.Parse(data);
JArray players = (JArray)o["response"]["players"];
if (players.Count > 0)
{
int PrivacyLevel = (int)players[0]["communityvisibilitystate"];
string username = (string)players[0]["personaname"];
string ProUrl = (string)players[0]["profileurl"];
double LastLogOff = (double)players[0]["lastlogoff"];
int CurrentStatus = (int)players[0]["personastate"];
int GamePlaying = (int)players[0]["gameid"];
textBox2.Text = "your username is " + username + "\n";
textBox2.Text = "You last logged off on " + ConvertUnix(LastLogOff) + "\n";
if (PrivacyLevel == 3)
{
textBox2.Text = "This user's account is public";
}
else if (PrivacyLevel == 1)
{
textBox2.Text = "This user's account is private";
}
switch (CurrentStatus)
{
case 1:
textBox2.Text = "This user is offline";
break;
case 2:
textBox2.Text = "This User is online and playing";
break;
}
}
else
{
textBox2.Text = "You have entered the SteamID incorrectly";
}
Console.ReadLine(); // Don't remove you idiot
}
public static DateTime ConvertUnix(double unixTimeStamp)
{
// Unix timestamp is seconds past epoch
System.DateTime dtDateTime = new DateTime(1970, 1, 1, 0, 0, 0, 0, System.DateTimeKind.Local);
dtDateTime = dtDateTime.AddSeconds(unixTimeStamp).ToLocalTime();
return dtDateTime;
}
}
the output of this code will be the last textbox2.text so in this case it would be the switch statement. I know I haven't explained it the best but I just don't know why this is happening, Thanks
You should use textBox2.Text += "more text to be added to the text box" instead of textBox2.Text = "more text to be added to the text box"
The problem here is that by using textBox2.Text =, you're overwriting the value. Instead, if you want to add lines, use textBox2.Text += "myString";. This will append the string to the textbox instead of overwriting it.
you should use += operator after first equal.
textBox2.Text = "your username is " + username + "\n";
textBox2.Text += "You last logged off on " + ConvertUnix(LastLogOff) + "\n";
if (PrivacyLevel == 3)
{
textBox2.Text += "This user's account is public";
}
else if (PrivacyLevel == 1)
{
textBox2.Text += "This user's account is private";
}
switch (CurrentStatus)
{
case 1:
textBox2.Text += "This user is offline";
break;
case 2:
textBox2.Text += "This User is online and playing";
break;
}
}
else
{
textBox2.Text += "You have entered the SteamID incorrectly";
}
the answer is as they describe above but I would like to suggest that you use a
richtextbox since you have more than one message and it would be better if you display them in Separate lines to do so
richtextbox1.text="\r\n"+some string;
the "\r\n" is to go to new line and then insert the text in that new line
.

How to change value in xml string?

I have the following method
string UpdateXmlString(string xmlString) {...}
I would like to find all tags which name contain password and delete a value;
Before:
<job xmlns:i=\"...\" xmlns=\"...">
<password>asdfasdf</password>
<adminPassword>asd</adminPassword>
...</job>
Expected result:
<job xmlns:i=\"..." xmlns=\"...">
<password></password>
<adminPassword></adminPassword>
...</job>
How to implement this method?
You should simply be using XmlDocument or XDocument to parse this. I wouldn't manipulate XML strings manually.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml;
using System.Xml.Linq;
namespace XDocumentTest
{
class Program
{
static void Main(string[] args)
{
try
{
String xml = "<?xml version=\"1.0\"?><rootElement>";
xml += "<user id=\"1\"><password>temp</password></user>";
xml += "<user id=\"2\"><adminPassword>foobar</adminPassword></user>";
xml += "<user id=\"3\"><somePassWORDelement>foobarXYZ</somePassWORDelement></user>";
xml += "</rootElement>";
XDocument doc = XDocument.Parse(xml);
foreach (XElement element in doc.Descendants().Where(
e => e.Name.ToString().ToLower().Contains("password")))
{
Console.WriteLine(element);
// Delete your value here. Either changing the text node
// or by removing the password node. E.g.
element.Value = string.Empty;
}
Console.WriteLine(doc.ToString());
}
catch (Exception e)
{
Console.WriteLine(e);
}
while (Console.ReadKey(true).Key != ConsoleKey.Escape)
{
}
}
}
}
You should use XPathNavigator.
In MSDN are some examples that will help you:
https://msdn.microsoft.com/en-us/library/zx28tfx1(v=vs.110).aspx
var doc = XDocument.Load(path);
var element = doc.Descendants("YOUR_Descendants")
.Where(arg => arg.Attribute("ExampleID").Value == "3" )//
.Single();
element.Element("UpdateElements")
.Element("UpdateElements_fc").Value = "222";// update
doc.Save(path); //save

Deleting XML element nodes

I want to delete an Element Node and all its Child Elements in a local xml-file by using C#.
This is my xml-file:
<?xml version="1.0" encoding="UTF-8"?>
<data>
<cocktail name="43 Hedonism" id="14">
<name>43 Hedonism</name>
<id>14</id>
</cocktail>
<cocktail name="B-52" id="4">
<name>B-52</name>
<id>4</id>
</cocktail>
</data>
I want to remove a cocktail Element where the id-attribute is 4, which is stored in a variable.
How can I tell my app that it only has to delete the cocktail Element where the id is 4?
XmlNode.RemoveChild will not work since it isn't supported/available in Windows Phone 8.
I wrote the following code but I'm stuck on where to write the id of the element I want to remove.
using System;
using System.IO;
using System.IO.IsolatedStorage;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Resources;
using System.Windows.Controls;
using System.Windows.Navigation;
using Microsoft.Phone.Controls;
using Microsoft.Phone.Shell;
using XmlLocalDelete1.Resources;
using System.Xml;
using System.Xml.Linq;
using System.Text;
namespace XmlLocalDelete1
{
public partial class MainPage : PhoneApplicationPage
{
// Constructor
public MainPage()
{
InitializeComponent();
// Sample code to localize the ApplicationBar
//BuildLocalizedApplicationBar();
}
private string id = "4";
protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
try
{
tb1.Text = "";
// copy the xml file to isolated storage
using (IsolatedStorageFile file = IsolatedStorageFile.GetUserStoreForApplication())
{
if (!file.FileExists("bar.xml"))
{
StreamResourceInfo sr_en = Application.GetResourceStream(new Uri("Resources\\bar.xml", UriKind.Relative));
using (BinaryReader br_en = new BinaryReader(sr_en.Stream))
{
byte[] data = br_en.ReadBytes((int)sr_en.Stream.Length);
//Write the file.
using (BinaryWriter bw = new BinaryWriter(file.CreateFile("bar.xml")))
{
bw.Write(data);
bw.Close();
}
}
}
// work with file at isolatedstorage
using (IsolatedStorageFileStream stream = new IsolatedStorageFileStream("bar.xml", FileMode.Open, file))
{
XDocument doc = XDocument.Load(stream, LoadOptions.None);
// delete node
XElement deleteThis = doc.Element("cocktail");
deleteThis.Remove();
}
// Write remaining Xml to textblock
using (IsolatedStorageFileStream stream = new IsolatedStorageFileStream("bar.xml", FileMode.Open, file))
{
// Load the XML file
XmlReader reader = XmlReader.Create(stream);
while (reader.Read())
{
switch (reader.NodeType)
{
case XmlNodeType.Element: // Het knooppunt is een element.
//tb1.Text = tb1.Text + "<" + reader.Name;
while (reader.MoveToNextAttribute()) // Attributen lezen.
tb1.Text = tb1.Text + " " + reader.Name + "='" + reader.Value + "'";
//tb1.Text = tb1.Text + ">";
break;
case XmlNodeType.Text: //De tekst in elk element weergeven.
//tb1.Text = tb1.Text + reader.Value + "\r\n";
Console.WriteLine(reader.Value);
break;
case XmlNodeType.EndElement: //Het einde van het element weergeven.
Console.Write("</" + reader.Name);
Console.WriteLine(">");
break;
}
}
reader.Close();
}
}
}
catch (Exception myExc)
{
Console.WriteLine(myExc.Message);
}
}
}
}
I want to remove a cocktail Element where the id-attribute is 4,
var xDoc = XDocument.Load(filename); //or XDocument.Load(stream);
xDoc.Descendants("cocktail").First(c => c.Attribute("id").Value == "4").Remove();
string newXml = xDoc.ToString();
OR using XPATH
xDoc.XPathSelectElement("//cocktail[#id='4']").Remove();
I would recommend you use XDocument instead XmlReader. In that case the task will be much easier.
XDocument xdoc = XDocument.Load(filename);
xdoc.Root.Elements().Where(x => x.Attribute("id").Value == "4").Remove();
xdoc.Save(filename);
I would use the XmlReader only for large xml files.
Searching and manipulation xml files is much easier with XmlDocument or better XDocument.

Categories