Programming Forums
User Name Password Register
 

RSS Feed
FORUM INDEX | TODAY'S POSTS | UNANSWERED THREADS | ADVANCED SEARCH

Reply
 
Thread Tools Display Modes
Old Dec 16th, 2005, 7:17 PM   #1
tayspen
Hobbyist Programmer
 
Join Date: Sep 2005
Location: A House...
Posts: 191
Rep Power: 4 tayspen is on a distinguished road
XML trouble

i have an XML file that looks like this

<?xml version="1.0" encoding="utf-8" ?>
<shortcuts>
	<key value="Technology">http://www.nytimes.com/services/xml/rss/nyt/Technology.xml</key>
	<key value="Sports">http://www.nytimes.com/services/xml/rss/nyt/Sports.xml</key>
	<key value="International">http://www.nytimes.com/services/xml/rss/nyt/International.xml</key>
</shortcuts>

then i have to textbox's on a button click i want to append to this xml file. the first textbox (des) and the second (feedname). So if in des i have Test and in feed name i have programminforums.org. When it appends it will have everything already in there but before

Quote:
</shortcuts>
it wouuld add this

Quote:
<key value="Test">www.programmingforums.org</key>
So say that the xml already consisted of


<?xml version="1.0" encoding="utf-8" ?>
<shortcuts>
	<key value="Technology">http://www.nytimes.com/services/xml/rss/nyt/Technology.xml</key>
	<key value="Sports">http://www.nytimes.com/services/xml/rss/nyt/Sports.xml</key>
	<key value="International">http://www.nytimes.com/services/xml/rss/nyt/International.xml</key>
</shortcuts>

After the writeing it would then be

<?xml version="1.0" encoding="utf-8" ?>
<shortcuts>
	<key value="Technology">http://www.nytimes.com/services/xml/rss/nyt/Technology.xml</key>
	<key value="Sports">http://www.nytimes.com/services/xml/rss/nyt/Sports.xml</key>
	<key value="International">http://www.nytimes.com/services/xml/rss/nyt/International.xml</key>
value="Test">www.programmingforums.org</key>
</shortcuts>
I hope that makes sense.

any ways here is the code that i tried. It for somereason justs overwrites the whol file

 //just start out our string builder
            StringBuilder sb = new StringBuilder();
            //add the xml heading
            sb.Append("<?xml version=\"1.0\" encoding=\"utf-8\" ?>" + "\r\n");
            //add our root node.
            sb.Append("<shortcuts>" + "\r\n");
            //add all our child nodes
        
            

                sb.Append("\t" + "<key value=\"" + des.Text + "\">" + feedname.Text + "</key>" + "\r\n");
            
            
            //add the end of the root node
            sb.Append("</shortcuts>");
            //get our stream writer to write the file, (no appending)
            StreamWriter sw = new StreamWriter(Application.StartupPath + "\\Feeds.xml", false);
            //write to the file
            sw.Write(sb.ToString());
            //save the file and dispose of the writer
            sw.Close();
            sw = null;

Thanks

-T
tayspen is offline   Reply With Quote
Old Dec 16th, 2005, 7:35 PM   #2
Dameon
Troll
 
Dameon's Avatar
 
Join Date: Apr 2005
Location: Texas
Posts: 732
Rep Power: 4 Dameon is on a distinguished road
It looks like you have the append paramter set to false in the streamwriter constructor.
http://msdn.microsoft.com/library/de...ctorTopic4.asp

Using the XML classes might be a tad more robust and easier.
http://msdn.microsoft.com/library/de...classtopic.asp

I can provide an example of how to use XmlDocument rather than StreamWriter for the given problem if you need.
__________________
MD5(sig) = bcef75433db02e9ad9bf81d6f7c5c270
Dameon is offline   Reply With Quote
Old Dec 16th, 2005, 7:55 PM   #3
tayspen
Hobbyist Programmer
 
Join Date: Sep 2005
Location: A House...
Posts: 191
Rep Power: 4 tayspen is on a distinguished road
Yea an XML example would be nice

Thanks

-T
tayspen is offline   Reply With Quote
Old Dec 16th, 2005, 8:47 PM   #4
Dameon
Troll
 
Dameon's Avatar
 
Join Date: Apr 2005
Location: Texas
Posts: 732
Rep Power: 4 Dameon is on a distinguished road
With pleasure.

		[STAThread]
		static void Main(string[] args) 
		{
			string path = Environment.CurrentDirectory + "\\Feeds.xml";
			
			StreamReader reader = null;
			try
			{
				reader = new StreamReader(path);
			}
			catch (Exception ex)
			{
				Console.WriteLine("Failed to open " + path + ". " + ex.Message);
			}
			
			Console.WriteLine("Opened " + path);

			XmlDocument doc = new XmlDocument();
			doc.Load(reader);
			reader.Close();
			
			Console.WriteLine("XML document read. Document root contains " + 
				doc.ChildNodes.Count + " child nodes.");

			//Get the first shortcuts element off the root
			XmlNode shortcuts = doc.SelectSingleNode("/shortcuts");
			
			Console.Write("Category: ");
			string cat = Console.ReadLine();
			cat = cat.Trim();
			if (cat == "")
			{
				Console.WriteLine("You must enter a category.");
				return;
			}
			Console.Write("URL: ");
			string url = Console.ReadLine();
			url = url.Trim();
			if (url == "")
			{
				Console.WriteLine("You must enter a category.");
				return;
			}

			//A shiny new element for our doc tree
			XmlElement urlElement = doc.CreateElement("key");
			//And an attribute to boot.
			XmlAttribute valueAttr = doc.CreateAttribute("value");
			valueAttr.Value = cat;
			//The URL is somewhat important as well
			XmlText urlElementText = doc.CreateTextNode(url);
			
			urlElement.Attributes.Append(valueAttr);
			urlElement.AppendChild(urlElementText);
			
			//Last but not least, stick the new element into the shortcuts element.
			shortcuts.AppendChild(urlElement);
			
			StreamWriter writer = null;
			try
			{
				//Overwrite the existing file. We are going to write to it. Nobody
				//else is allowed to touch it until we are done.
				writer = new StreamWriter(
					File.Open(path, FileMode.Create, FileAccess.Write,
					FileShare.None));
			}
			catch (Exception ex)
			{
				Console.WriteLine("Failed to open " + path + " for writing. " + ex.Message);
			}

			doc.Save(writer);
			writer.Close();
			Console.WriteLine("Saved!");
		}

Feel free to ask for clarification.
__________________
MD5(sig) = bcef75433db02e9ad9bf81d6f7c5c270
Dameon is offline   Reply With Quote
Old Dec 16th, 2005, 10:13 PM   #5
tayspen
Hobbyist Programmer
 
Join Date: Sep 2005
Location: A House...
Posts: 191
Rep Power: 4 tayspen is on a distinguished road
Thank you very mmuch. That worked perfect. Thanks again

But no my next question. I think this one will be a little tougher. As you know in the document there are different items. And they are loaded in to a listview using this code.

//open the file
            string ConfigLoc = Application.StartupPath + "\\Feeds.xml";
            XmlTextReader reader = new XmlTextReader(ConfigLoc);
            //ignore white space
            reader.WhitespaceHandling = WhitespaceHandling.None;
            //start xml doc
            XmlDocument doc = new XmlDocument();
            //load file text into xml doc
            doc.Load(reader);
            //close file reader
            reader.Close();
            //select root node
            XmlNode root = doc.SelectSingleNode("shortcuts");
            //clear anything out of the list view
            listBox2.Items.Clear();
            //loop through all the children
            foreach (XmlNode shortcuts in root.ChildNodes)
            {
                //get the value and key
                string shortcutKey = shortcuts.Attributes[0].Value;
                string shortcutValue = shortcuts.ChildNodes[0].Value;
                //add the value and key to a list item
                ListViewItem lvi = new ListViewItem();
                lvi.Text = shortcutKey;
                lvi.SubItems.Add(shortcutValue);
                //then to the listview
                listBox2.Items.Add(lvi);
                lvi = null;

            }

And that code to load works well . But i want to give the user the option to delete an item from the listview. thatwould involve only deleting that line from the XML. How could this be done.

-T
tayspen is offline   Reply With Quote
Old Dec 17th, 2005, 8:38 AM   #6
Dameon
Troll
 
Dameon's Avatar
 
Join Date: Apr 2005
Location: Texas
Posts: 732
Rep Power: 4 Dameon is on a distinguished road
Mapping an item in a ListView to your actual data is a frequent question. Using the Tag property for each ListViewItem to store a reference to the data that the ListViewItem represents works well. In your case, you could set it to the XmlNode called shortcuts between where you instantiate the ListViewItem and when you add it to the listview. However, it is unlikely that your internal representation of these shortcuts is purely a bunch of XmlNodes. If you have a class to internally represent a shortcut that just hasn't been posted, I would set Tag to an instance of it instead of an XmlNode. At that point, you could add a member to your shortcut class that holds the XmlNode reference. This would allow manipulation of the node as the shortcut changes in memory (the magic of properties) as well as removal from the document tree when it is removed from your shortcut list. After that, it's just a matter of saving the document at your user's whim to reflect your changes.

It would be best to add some more safety in your loop. The first attribute isn't always the one that you want and there may not even be one. The same goes for ChildNodes. Since you know that you are dealing with XmlElements rather than the more generic XmlNode, you could cast the return of SelectSingleNode to an XmlElement to take advantage of its additional methods and properties for manipulating attributes and children.
__________________
MD5(sig) = bcef75433db02e9ad9bf81d6f7c5c270
Dameon is offline   Reply With Quote
Old Dec 17th, 2005, 10:02 AM   #7
tayspen
Hobbyist Programmer
 
Join Date: Sep 2005
Location: A House...
Posts: 191
Rep Power: 4 tayspen is on a distinguished road
Lol, you lost me. With all that tag and node talk. So deleteing just a specific option is hard? Its just not a quick snippet of code? Example?
tayspen is offline   Reply With Quote
Old Dec 17th, 2005, 10:25 AM   #8
Dameon
Troll
 
Dameon's Avatar
 
Join Date: Apr 2005
Location: Texas
Posts: 732
Rep Power: 4 Dameon is on a distinguished road
//open the file
            string ConfigLoc = Application.StartupPath + "\\Feeds.xml";
            XmlTextReader reader = new XmlTextReader(ConfigLoc);
            //ignore white space
            reader.WhitespaceHandling = WhitespaceHandling.None;
            //start xml doc
            XmlDocument doc = new XmlDocument();
            //load file text into xml doc
            doc.Load(reader);
            //close file reader
            reader.Close();
            //select root node
            XmlNode root = doc.SelectSingleNode("shortcuts");
            //clear anything out of the list view
            listBox2.Items.Clear();
            //loop through all the children
            foreach (XmlNode shortcuts in root.ChildNodes)
            {
                //get the value and key
                string shortcutKey = shortcuts.Attributes[0].Value;
                string shortcutValue = shortcuts.ChildNodes[0].Value;
                //add the value and key to a list item
                ListViewItem lvi = new ListViewItem();

lvi.Tag = shortcuts; //Remember what node this listviewitem is talking about

lvi.Text = shortcutKey;
                lvi.SubItems.Add(shortcutValue);
                //then to the listview
                listBox2.Items.Add(lvi);
                lvi = null;

            }

And when you need to remove the selected item:
XmlNode selectedNode = null;
foreach (ListViewItem lvi in ListBox2.SelectedItems)
{
	 if (lvi.Tag != null)
	 {
		  selectedNode = (XmlNode)lvi.Tag;
		  if (selectedNode.Parent != null)
		  {
			   selectedNode.Parent.RemoveChild(selectedNode);
		  }
	 }
}
//Remove the selected items from the list now
__________________
MD5(sig) = bcef75433db02e9ad9bf81d6f7c5c270
Dameon is offline   Reply With Quote
Old Dec 17th, 2005, 4:01 PM   #9
tayspen
Hobbyist Programmer
 
Join Date: Sep 2005
Location: A House...
Posts: 191
Rep Power: 4 tayspen is on a distinguished road
Lol thanks man. but i had to modify the code a little to this

XmlNode selectedNode = null;
            foreach (ListViewItem lvi in listBox2.SelectedItems)
            {
                if (lvi.Tag != null)
                {
                    selectedNode = (XmlNode)lvi.Tag;
                    if (selectedNode.ParentNode != null)
                    {
                        selectedNode.ParentNode.RemoveChild(selectedNode);
                    }
                }
            }

And it does not work. When i load the file again it still has the one i "deleted".
tayspen is offline   Reply With Quote
Old Dec 17th, 2005, 5:26 PM   #10
Dameon
Troll
 
Dameon's Avatar
 
Join Date: Apr 2005
Location: Texas
Posts: 732
Rep Power: 4 Dameon is on a distinguished road
Did you...
a) Set the Tag property when populating the list
b) Call Save on the XmlDocument
c) Add some debug output/breakpoints to see if control is reaching critical parts of the code
__________________
MD5(sig) = bcef75433db02e9ad9bf81d6f7c5c270
Dameon is offline   Reply With Quote
Reply

Bookmarks

« Previous Thread in Forum | Next Thread in Forum »

Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Forum Jump




DaniWeb IT Discussion Community
All times are GMT -5. The time now is 3:31 PM.

Powered by vBulletin® Version 3.7.0, Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
Copyright ©2007 DaniWeb® LLC