Saving Particular Node in XML File - c#

I am populating textboxes with information from a particular node based on it's ConfirmNum. Then when all info is updated, I am saving information (by a submit button) back to the particular node.
However, upon saving, every node in the XML file that was empty drops down to another line.
Example XML Before Save:
<OnlineBanking>
<Transactions>
<Txn>
<Login></Login>
<UserName>userName</UserName>
<CustomerName>CustomerName</CustomerName>
<ConfirmNum>1234</ConfirmNum>
</Txn>
</Transactions>
</OnlineBanking>
My code (below) will save the information for that node, based on the Page.aspx?CID=1234 number. However, every node in the entire XML file that was blank, will now have a line break in it. Not just the Txn we just edited, but all.
Here is my code:
protected void btnSubmit_Click(object sender, EventArgs e)
{
XmlDocument item = new XmlDocument();
item.Load(xmlFileName);
if (CID != "")
{
XmlNode xlist = item.SelectSingleNode("OnlineBanking/Transactions/Txn[ConfirmNum=" + CID + "]");
if (xlist != null)
{
xlist.ChildNodes.Item(0).InnerText = tbLogin.Text;
xlist.ChildNodes.Item(1).InnerText = tbUserName.Text;
xlist.ChildNodes.Item(2).InnerText = tbCustomerName.Text;
item.Save(xmlFileName);
}
}
}
Example XML After Save:
<OnlineBanking>
<Transactions>
<Txn>
<Login>
</Login>
<UserName>userName</UserName>
<CustomerName>CustomerName</CustomerName>
<ConfirmNum>1234</ConfirmNum>
</Txn>
</Transactions>
</OnlineBanking>
Note how the <login> is on another line than </login>. This is what I am talking about. Hope someone can see clearly what I am not doing.

Try setting the PreserveWhitespace property to True and see if it will stop inserting line breaks upon calling Save:
XmlDocument item = new XmlDocument();
item.PreserveWhitespace = true;
item.Load(xmlFileName);

One compromise is:
if(string.IsNullOrWhiteSpace(tbLogin.Text))
xlist.ChildNodes.Item(0).IsEmpty = true;
else
xlist.ChildNodes.Item(0).InnerText = tbLogin.Text;
This will give you:
<Login />

Related

updating an inner text of xml node after changing the value in datagridview

i have a small issue...first, i have to read the xml file and extract Arg.2 in a datagridview...then i have to update the value in the datagrid. finally when pressing the update button, i need this value to be written into Arg.2 again and save the xml file with a new name.
i can read the value when extracted and when updated in a message box but i can't see it in the xml file...please let me know what is wrong.
below is the code under button_click:
openFileDialog1.ShowDialog();
XmlDocument Newdoc = new XmlDocument();
Newdoc.Load(openFileDialog1.FileName);
w = dataGridView1.Rows[0].Cells["Arg2"].Value.ToString();
Newdoc.SelectSingleNode(".//event[#type='2VO']/properties/media[#Arg2]").InnerText = w;
MessageBox.Show(Newdoc.SelectSingleNode(".//event[#type='2VO']/properties/media[#Arg2]").InnerText);
Newdoc.Save(#"C:\download\updatedxml.xml");
strangely, when checking the new updatedxml file, i saw that the value is getting updated in a very strange position...see below (2100 position):
<event type="2VO">
<properties>
<schedule startType="-ParentEnd" startOffset="00:00:33:00" endType="Duration" endOffset="00:00:22:00" />
<event title="Pixel VO" reconcileKey="106251137" />
<mediaStream>
<cg type="PIXEL CG" />
<allocation type="ListStream">
<listStream type="Fixed" listStreamNo="0" />
</allocation>
</mediaStream>
<media RuleCode="2VO" Arg1="TUE" Arg2="1940" Arg3="O1T13810" Arg4="" Arg5="" Arg6="" Arg7="" Arg8="">2100</media>
which is not the position needed...is there anything wrong with my Xpath?
do that like this and check validation like node exist or not check your XPath
try
{
XmlDocument doc = new XmlDocument();
doc.Load(yourDoc); //load youe xml doc
doc.SelectSingleNode("your node").InnerText = "new text";//select your node which you want to update
doc .Save(#"C:\download\updatedxml.xml");
//then show your message box
}
catch(exception ex)
{
//catch exception here
}
then show your message box
i figured out the issue...it was an issue with the Xpath...so when i modified it to (.//#Arg.2).innertext, it worked fine.

Add Text Information to Different XML Element each time information is submitted c#

I have an XML file that collects information with Button_Click, so it starts off empty.
XML Sample
<marina>
<dockone>
</dockone>
<docktwo>
</docktwo>
</marina>
When I submit information from a textbox, a new XmlNode is created called slipone, and another XmlNode called reg is nested within that.
XML Sample 2
<marina>
<dockone>
<slipone>
<reg>12345</reg>
<slipone>
</dockone>
<docktwo>
</docktwo>
</marina>
I have attempted to create an if/else statement that will add a new XmlNode called sliptwo, with reg still nested within it, if slipone already has text, like so:
<marina>
<dockone>
<slipone>
<reg>12345</reg>
<slipone>
<sliptwo>
<reg>67890</reg>
<sliptwo>
</dockone>
<docktwo>
</docktwo>
</marina>
However the closest I have gotten is another XMlnode is still created, however it labels itself as slipone, and I am not sure what I am doing wrong:
<marina>
<dockone>
<slipone>
<reg>12345</reg>
<slipone>
<slipone>
<reg>67890</reg>
<slipone>
</dockone>
<docktwo>
</docktwo>
</marina>
This is an example of what I have been playing around with. Ignore the operators as I have resorted to trial and error but still have gotten nowhere. Please help!
C# Example
XmlDocument XmlDocObj1 = new XmlDocument();
XmlDocObj1.Load(Server.MapPath("~/App_Data/SlipData.xml"));
XmlNode rootnode1 = XmlDocObj1.SelectSingleNode("marina/dockone");
XmlNode dockone = rootnode1.AppendChild(XmlDocObj1.CreateNode(XmlNodeType.Element, "slipone", ""));
XmlNode docktwo = rootnode1.AppendChild(XmlDocObj1.CreateNode(XmlNodeType.Element, "sliptwo", ""));
XmlNode dockthree = rootnode1.AppendChild(XmlDocObj1.CreateNode(XmlNodeType.Element, "slipthree", ""));
if (regfinal.Text != dockone.InnerText)
{
dockone.AppendChild(XmlDocObj1.CreateNode(XmlNodeType.Element, "Reg", "")).InnerText = regfinal.Text;
XmlDocObj1.Save(Server.MapPath("/App_Data/SlipData.xml"));
}
else if (regfinal.Text == dockone.InnerText)
{
docktwo.AppendChild(XmlDocObj1.CreateNode(XmlNodeType.Element, "Reg", "")).InnerText = regfinal.Text;
XmlDocObj1.Save(Server.MapPath("/App_Data/SlipData.xml"));
}
Your logic isn't going to do what I think you are saying since the only time (regfinal.Text != dockone.InnerText) will evaluate to false is when you enter nothing in your text control.
I believe you might mean to say if dockone exists then create another node called docktwo. This will require you to change your logic.
Some very simple code to get you a bit farther down the path. Not intended to be perfect or solve all problems...
private void button1_Click(object sender, EventArgs e)
{
XmlDocument XmlDocObj1 = new XmlDocument();
XmlDocObj1.Load(AppDomain.CurrentDomain.BaseDirectory.ToString()+"test.xml");
XmlNode rootnode1 = XmlDocObj1.SelectSingleNode("marina/dockone");
XmlNode dockone = rootnode1.AppendChild(XmlDocObj1.CreateNode(XmlNodeType.Element, "slipone", ""));
XmlNode docktwo = rootnode1.AppendChild(XmlDocObj1.CreateNode(XmlNodeType.Element, "sliptwo", ""));
XmlNode dockthree = rootnode1.AppendChild(XmlDocObj1.CreateNode(XmlNodeType.Element, "slipthree", ""));
//jsh: old logic
//if (textBox1.Text != dockone.InnerText)
//new logic to test whether we have already created the dockone node which should only occur once
//you already have the logic for selecting the dockone node above...now just test if you already have it.
//NOTE: you may actually want a switch statement given that you avhe dockone, docktwo, and dockthree or at least another
// if statement to see if docktwo has been created and thus creaste dockthree.
if (rootnode1 == null )
{
dockone.AppendChild(XmlDocObj1.CreateNode(XmlNodeType.Element, "Reg", "")).InnerText = textBox1.Text;
XmlDocObj1.Save(AppDomain.CurrentDomain.BaseDirectory.ToString() + "test.xml");
}
//else if (textBox1.Text == dockone.InnerText) jsh: old logic
else
{
docktwo.AppendChild(XmlDocObj1.CreateNode(XmlNodeType.Element, "Reg", "")).InnerText = textBox1.Text;
XmlDocObj1.Save(AppDomain.CurrentDomain.BaseDirectory.ToString() + "test.xml");
}
}

Parsing XML in a foreach loop

I am making a Application on Windows Phone 8. The bit I am struggling with is getting the XML parsed.
Here the XML File:
<ArrayOfThemeParkList xmlns="http://schemas.datacontract.org/2004/07/WCFServiceWebRole1" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<ThemeParkList>
<id>1</id>
<name>Alton Towers</name>
</ThemeParkList>
<ThemeParkList>
<id>2</id>
<name>Thorpe Park</name>
</ThemeParkList>
<ThemeParkList>
<id>3</id>
<name>Chessington World Of Adventures</name>
</ThemeParkList>
<ThemeParkList>
<id>4</id>
<name>Blackpool Pleasure beach</name>
</ThemeParkList>
</ArrayOfThemeParkList>
And the c# code that tries to parse it is:
void ThemeParksNames_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
{
//Now need to get that data and display it on the page
//check for errors
if (e.Error == null)
{
//No errors have been passed now need to take this file and parse it
//Its in XML format
XDocument xdox = XDocument.Parse(e.Result);
//need a list for them to be put in to
List<ThemeParksClass> ParkList = new List<ThemeParksClass>();
//Now need to get every element and add it to the list
foreach (XElement item in xdox.Root.Elements("ThemeParkList"))
{
ThemeParksClass content = new ThemeParksClass();
content.ID = Convert.ToInt32(item.Element("id").Value);
content.ThemeParkName = item.Element("name").Value.ToString();
ParkList.Add(content);
}
parkList.ItemsSource = ParkList.ToList();
}
else
{
//There an Error
}
}
Now when using Break points it get to the for each loop but does not run at all just moves on. I am guessing i have the for each loop set wrong.
Many Thanks.
Your ThemeParkList elements are in a namespace http://schemas.datacontract.org/2004/07/WCFServiceWebRole1 - you'll need to adjust accordingly:
XNamespace ns = "http://schemas.datacontract.org/2004/07/WCFServiceWebRole1";
foreach (XElement item in xdox.Descendants(ns + "ThemeParkList"))
You'll need to handle the other elements in the same way.

Selecting random nodes from xml file

My application allows the user to speak into a microphone and the program will talk back to the user. I have responses saved in a XML file and when the user talks, I want the program to check in the XML file and display a random node in the section it should. The following is what my XML file looks like:
<?xml version="1.0" encoding="utf-8" ?>
<MarcusXMLFile xmlns:Responses="http://www.rewardstrike.com/XMLFile1.xml"">
<response>
<posanswer>
<answer>Yes, sir.</answer>
<answer>Right away.</answer>
</posanswer>
</response>
</MarcusXMLFile>
My code for selecting a random node is:
private void Responses()
{
string query = String.Format("http://www.rewardstrike.com/XMLFile1.xml");
XmlDocument Responses = new XmlDocument();
Responses.Load(query);
XmlNode channel = Responses.SelectSingleNode("MarcusXMLFile");
XmlNodeList nodes = Responses.SelectNodes("MarcusXMLFile/response");
try
{
XmlNodeList positiveresponses = Responses.SelectNodes("./posanswer/answer");
foreach (XmlNode ans in positiveresponses.Cast<XmlNode>().OrderBy(elem => Guid.NewGuid()))
{
response = ans.InnerText;
}
QEvent = "positiveresponse";
}
catch { }
}
And my code for calling the event is:
case "Hello":
case "Hello Jarvis":
Responses();
if (QEvent == "positiveresponse")
{
JMARCUS.Speak(response);
}
break;
However, when I speak to the application, it gives me an error saying the text he is supposed to speak in null. Any ideas?
Your second Responses.SelectNodes finds no nodes, so positiveresponses has no nodes, the foreach loop has nothing to iterate on, and response is never assigned a value.
Try changing:
XmlNodeList positiveresponses = Responses.SelectNodes("./posanswer/answer");
To:
XmlNodeList positiveresponses
= Responses.SelectNodes("MarcusXMLFile/response/posanswer/answer");

c# - Want to perform an action if a user enters a node that already exists in a xml file

Bassicly im creating a schedule where the user can input his on time such as 19/4/2012, and it gets saved into an xml file such as 19/4/2012. Im trying to perform an action that if the user enters information that has already been entered into the xml file then display a error. Im still unsure how to do such a task so any help would be appreciated thanx.
Example of xml:
<Schedule>
<Date>19/4/2012</Date>
</Schedule>
Code Example:
private void button1_Click(object sender, EventArgs e)
{
XmlDocument doc = new XmlDocument();
doc.Load("xmldoc.xml");
XmlNode schedule = doc.CreateElement("Schedule");
XmlNode date = doc.CreateElement("Date");
date.InnerText = monthCalendar1.SelectionStart.ToString();
schedule.AppendChild(date);
doc.DocumentElement.AppendChild(schedule);
doc.Save("xmldoc.xml");
if(date.InnerText == monthCalander1.SelectionStart.ToString())
{
label6.Text = "Incorrect";
}
}
}
Well you need to check if the date exists before you add a new schedule. You can probably do something like :
if (doc.SelectSingleNode("/Schedule/Date[text()='" + monthCalander1.SelectionStart.ToString() + "']") != null){
// already exists, do something here
}

Categories