Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations gkittelson on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Problem with putting XML data in variables

Status
Not open for further replies.

Raenius

Programmer
Oct 14, 2003
77
NL
Hi all,

I've got a settings.xml file in which are some default settings I want to display on a form in a application.

The settings.xml is built up like this:

<router>
<name>Test</name>
<ip>192.168.100.3</ip>
<description>Hello</description>
<ttl>255</ttl>
<threshold>100</threshold>
<suspended>no</suspended>
</router>

I want to place the data within the XMl into a few variables....this is the code I have so far.

try
{
XmlDocument xd = new XmlDocument();
XmlTextReader xmlreader = new XmlTextReader(&quot;C:\\settings.xml&quot;);

string test = xmlreader.ReadString();

if (test != null)
{
xd.InnerXml = test;

XmlNode RouterNode = xd.ChildNodes[0];
XmlNode NameNode;
XmlNode IPNode;
XmlNode DescriptionNode;
XmlNode TTLNode;
XmlNode ThresholdNode;
XmlNode SuspendedNode;

NameNode = RouterNode.ChildNodes[0];

// test
MessageBox.Show(NameNode.OuterXml);

IPNode = RouterNode.ChildNodes[1];
DescriptionNode = RouterNode.ChildNodes[2];
TTLNode = RouterNode.ChildNodes[3];
ThresholdNode = RouterNode.ChildNodes[4];
SuspendedNode = RouterNode.ChildNodes[5];

string routername = NameNode.InnerXml.ToString();
MessageBox.Show(routername);
// etc the rest of the nodes

}
}
catch(Exception ex)
{
MessageBox.Show(ex.Message);
}

When I run I get the exception: root element missing

Does someone have some tips or advice?

Thanks!

- Raenius


&quot;Free will...is an illusion&quot;
 
Heres some working code for you:

using System;
using System.Xml;

namespace testXml
{
/// <summary>
/// Summary description for Class1.
/// </summary>
class Class1
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main(string[] args)
{
XmlDocument mySettings = new XmlDocument();
mySettings.LoadXml(&quot;<router><name>Test</name><ip>192.168.100.3</ip><description>Hello</description> <ttl>255</ttl><threshold>100</threshold><suspended>no</suspended></router>&quot;);
string name = mySettings.DocumentElement.SelectSingleNode(&quot;//name&quot;).InnerText;
string ip = mySettings.DocumentElement.SelectSingleNode(&quot;//ip&quot;).InnerText;
string description = mySettings.DocumentElement.SelectSingleNode(&quot;//description&quot;).InnerText;
string ttl = mySettings.DocumentElement.SelectSingleNode(&quot;//ttl&quot;).InnerText;
string threshold = mySettings.DocumentElement.SelectSingleNode(&quot;//threshold&quot;).InnerText;
string suspended = mySettings.DocumentElement.SelectSingleNode(&quot;//suspended&quot;).InnerText;
Console.WriteLine(name + &quot;--&quot; + ip + &quot;--&quot; + description + &quot;--&quot; + ttl + &quot;--&quot; + threshold + &quot;--&quot; +suspended);
Console.ReadLine();
}
}
}

Stephan
 
I am now working on this piece of code you gave me...it worked when I copied it but not if I loaded my own XML file. Data root at level 1, line 1 is invalied or something like this. I saw someone else who had the same problem, I 'm figuring it out now... ;-)

Thanks a lot for your help!

- Raenius

&quot;Free will...is an illusion&quot;
 
You`ll might get a problem with this:
mySettings.LoadXml...
if you are loading the xml content from a file use
mySettings.Load(path);

Stephan
 
It works like a charm Stephan, only it stops working when I replace the XML string with a path to the XML file.

Then it gives: &quot;The data at the root level is invalid, level 1 line 1&quot;..

I think it has something to do with the use LoadXml instead of XMLTextReader?

- Raenius

&quot;Free will...is an illusion&quot;
 
As I said dont write mySettings.LoadXml(<?xml....
use mySettings.Load(&quot;c:\myFile.xml&quot;)

That should work.

Stephan
 
LOL my IE wasn't updated in time to see your second reply thats why I missed it.

Thanks for the clarification though...I am testing now..

&quot;Free will...is an illusion&quot;
 
Allright it seems to work beautifully, thanks a lot Stephan!

Thumbs up for you!

- Raenius

(I'll definitely run into more problems so I'll be back!)

&quot;Free will...is an illusion&quot;
 
Just an observation:
Doing this:
Code:
string ip = mySettings.DocumentElement.SelectSingleNode(&quot;//ip&quot;).InnerText;
without first checking to see if the SelectSingleNode brought back a valid Node will raise an exception when the element is missing. You can either break it up into a multi-step process:
Code:
string ip = &quot;&quot;;
XmlNode IpNode = mySettings.DocumentElement.SelectSingleNode(&quot;//ip&quot;)
if (null != IpNode)
{
   // got something!
   ip = IpNode.InnerText;
} else {
   // Didn't get anything (missing element)
   // Use default value?
   ip = &quot;127.0.0.1&quot;;
}
[code]
Or validate the XML against an XSD first to make sure it looks the way it ought to.  This code assumes the XML has a reference to the .XSD file embedded in it.
[code]
public ReadNValidate()
{
  XmlTextReader tr = new XmlTextReader(&quot;MyFile.xml&quot;);
  XmlValidatingReader vr = new XmlValidatingReader(tr);

  vr.ValidationType = ValidationType.Schema;
  vr.ValidationEventHandler += new ValidationEventHandler (ValidationHandler);

  while(vr.Read())
  {
  }
}

public static void ValidationHandler(object sender, ValidationEventArgs args)
{
  Console.WriteLine(&quot;***Validation error&quot;);
  Console.WriteLine(&quot;\tSeverity:{0}&quot;, args.Severity);
  Console.WriteLine(&quot;\tMessage:{0}&quot;, args.Message);
}
Chip H.


If you want to get the best response to a question, please check out FAQ222-2244 first
 
Here is an working example using the file you posted and is using a struct to store information for easy passing it to other functions.
Code:
internal struct RouterData
	{
		internal string name;
		internal string ip;
		internal string description;
		internal string ttl;
		internal string threshold;
		internal string suspended;
	}
	/// <summary>
	/// Summary description for Class1.
	/// </summary>
	class Class1
	{
		
		public Class1()
		{
		}
		private RouterData XLoad2(string XMLFile, ref RouterData data)
		{
			
			try
			{
				XmlDocument oXmlDocument = new XmlDocument();
				oXmlDocument.Load(XMLFile);
				System.Xml.XmlNode n = oXmlDocument.SelectSingleNode(&quot;//router&quot;);
				if (n!=null) 
				{
					n = oXmlDocument.SelectSingleNode(&quot;//name&quot;);
					if (n!=null) 
						data.name=n.InnerText;
					n = oXmlDocument.SelectSingleNode(&quot;//ip&quot;);
					if (n!=null) 
						data.ip= n.InnerText;
					n = oXmlDocument.SelectSingleNode(&quot;//description&quot;);
					if (n!=null) 
						data.description = n.InnerText;
					n = oXmlDocument.SelectSingleNode(&quot;//threshold&quot;);
					if (n!=null) 
						data.threshold = n.InnerText;
					n = oXmlDocument.SelectSingleNode(&quot;//suspended&quot;);
					if (n!=null) 
						data.suspended = n.InnerText;
					n = oXmlDocument.SelectSingleNode(&quot;//ttl&quot;);
					if (n!=null) 
						data.ttl = n.InnerText;
					
				}
		
			}
			catch(Exception e)
			{	
				string sMsg = &quot;Error parsing file &quot; + XMLFile + &quot;:&quot; +  e.GetType() + &quot;:&quot; + e.Message;
			}
			return data;
		}
}

How to use:
static void Main(string[] args)
{
        try
	{
		RouterData data = new RouterData();
		Class1 c1 = new Class1();
		c1.XLoad2(&quot;C:\\router.xml&quot;, ref data);
	}
        catch (Exception ex)
        {
        }
}

-obislavu-
 
Wow ppl, so many solutions!

The thing I need it for is that when a form is loaded, the textboxes are automatically filled in with default settings read from the settings.xml

I've got that working now when I change the settings.xml to the above described settings.xml, now I want to declare my settings.xml like this:

<settings>
<router>
<name />
<ip />
<etc etc>
<router>
<alerts>
<audio>
<enabled />
<up_wav />
<down_wav />
</audio>
<email>
<address />
<smtp />
<usr />
<pass />
</email>
</alerts>
</settings>

Would I go about in the same manner or would I need to run through it via a loop?

Thanks!

- Raenius




&quot;Free will...is an illusion&quot;
 
Once you've gotten the value from your XML, you assign it to the text property of a textbox:
Code:
txtIP.Text = IP;
txtTTL.Text = TTL;
Chip H.


If you want to get the best response to a question, please check out FAQ222-2244 first
 
Yes Chip, I already got that working but thanks anyway! ;-)

- Raenius

&quot;Free will...is an illusion&quot;
 
LOL I thought I'd ask another question in this thread.

I've got everything working now from getting the DATA out of the .XML file. But now I'm having a problem the other way around, I want to update the settings saved in the settings.xml file with variables from a windows form.

Can anyone point me in the right direction?

- Raenius

(ps. Thanks in advance)

&quot;Free will...is an illusion&quot;
 
You can write a function which takes parameters the node name you want to set and the new value to put there.
This function locates the node for which you want to change its value, set the InnerText property to that value and calls Save().

void UpdateSettings(string key, string val)
{
try
{
XmlDocument oXmlDocument = new XmlDocument();
oXmlDocument.Load(&quot;settings.xml&quot;);
System.Xml.XmlNode n = oXmlDocument.SelectSingleNode(key);
if (n!=null)
{
n.InnerText= val;
}
//
oXmlDocument.Save(&quot;settings.xml&quot;);

}catch()
{
}
}

UpdateSettings(&quot;//router//name&quot;,myForm.nameTextBox1.Text);
-obislavu-
 
Thanks Obislavu, I will try this asap and get back to you!

- Raenius

&quot;Free will...is an illusion&quot;
 
Just checked it out and it worked beautifully! Thanks a lot!

- Raenius

ps. Until next time!


&quot;Free will...is an illusion&quot;
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top