473,396 Members | 2,009 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,396 software developers and data experts.

Help Creating XmlNode / XmlAttribute Elegantly

I am creating a configuration class to read / write a standard configuration file.

<?xml version="1.0" encoding="utf-8"?>
<configuration>
<appSettings>
<add key="ConnectionString" value="server=(local);" />
</appSettings>
</configuration>

I am using a XmlDocument for my base implementation.

I am looking to see if there is a better way to add a new node / attribute than using
XmlDocument.InnerXml. I would consider this to be a hack but couldn't really see another
way of doing this without defining namespaces and the like.

I have included the full file below and the lines that I am wondering about are lines: 79, 227, and 266

Thanks,
Dave
===================================

using System;
using System.Xml;
using System.Text;

namespace Storage.Utility.Configuration
{
/// <summary>
/// Class for Reading / Writing Configuration Options
/// </summary>
public class Configuration
{
#region Data Members

private XmlDocument xmlDoc = null;
private XmlElement root = null;
private XmlNode node = null;

private string filename = null;
private string queryString = null;

#endregion

#region Constructor

public Configuration(string configFileName)
{
filename = configFileName;
}

#endregion

#region Methods

#region Miscellaneous

/// <summary>
/// Initialize the Configuration Class
/// </summary>
private void Initialize()
{
LoadConfiguration();
}

#endregion

#region File Access

/// <summary>
/// Reload the Configuration File
/// </summary>
public void ReloadConfiguration()
{
LoadConfiguration();
}
/// <summary>
/// Save the Configuration File
/// </summary>
public void Save()
{
SaveConfiguration();
}
/// <summary>
/// Load the Configuration File
/// </summary>
private void LoadConfiguration()
{
try
{
xmlDoc = new XmlDocument();
xmlDoc.Load(filename);
}
catch (Exception)
{
// Create Configuration File
xmlDoc.InnerXml = "<?xml version=\"1.0\" encoding=\"utf-8\"?><configuration></configuration>";
}
finally
{
root = xmlDoc.DocumentElement;
}
}
/// <summary>
/// Save the Configuration File
/// </summary>
private void SaveConfiguration()
{
try
{
xmlDoc.Save(filename);
}
catch (Exception ex)
{
// Can't do anything
throw (ex);
}
}

#endregion

#region Retrieve Values

/// <summary>
/// Get the Value of the Key
/// </summary>
/// <param name="section"></param>
/// <param name="key"></param>
/// <returns></returns>
public string GetValue(string section, string key)
{
try
{
// Find the Node
node = GetValueNode(section, key);
if (node != null)
{
// Retrieve Value
XmlNode valueNode = node.Attributes.GetNamedItem("value");
return (valueNode.Value);
}
}
catch (Exception)
{
// Nothing to do
}

// Error Occurred
return (null);
}
/// <summary>
/// Find the Node that the Key belongs to
/// </summary>
/// <param name="section"></param>
/// <param name="key"></param>
/// <returns></returns>
private XmlNode GetValueNode(string section, string key)
{
try
{
// XML Search Path
queryString = "/configuration/" + section + "/add[@key=\"" + key + "\"]";

// Look from the Root of the Document
return (root.SelectSingleNode(queryString));
}
catch (Exception)
{
// Nothing to do
}

// Error Occurred
return (null);
}

#endregion

#region Store Values

/// <summary>
/// Store Key / Value in Configuration File
/// </summary>
/// <param name="section"></param>
/// <param name="key"></param>
/// <param name="keyValue"></param>
/// <returns></returns>
public bool StoreValue(string section, string key, string keyValue)
{
try
{
// Find Node if it exists
node = GetValueNode(section, key);
if (node != null)
{
// Update Value
node = node.Attributes.GetNamedItem("value");
node.Value = keyValue;
return (true);
}

// Node Doesn't Exist -> Get/Create Section -> Add Key / Value
if (GetSection(section) == true)
return (CreateValueNode(section, key, keyValue));
}
catch (Exception)
{
// Nothing to do
}

// Error Occurred
return (false);
}

#endregion

#region Create Nodes

/// <summary>
/// Create New Key / Value Entry
/// </summary>
/// <param name="section"></param>
/// <param name="key"></param>
/// <param name="keyValue"></param>
/// <returns></returns>
private bool CreateValueNode(string section, string key, string keyValue)
{
try
{
// Get Section
queryString = "/configuration/" + section;
node = root.SelectSingleNode(queryString);

// Node Must Exist
if (node != null)
{
// Create and Add New Key / Value Entry
StringBuilder sb = new StringBuilder(500);
sb.Append("<add key=\""); sb.Append(key); sb.Append("\" ");
sb.Append("value=\""); sb.Append(keyValue); sb.Append("\" />");

node.InnerXml += sb.ToString();
return (true);
}
}
catch (Exception)
{
// Nothing to do
}

// Error Occurred
return (false);
}
/// <summary>
/// Get / Create a New Configuration Section
/// </summary>
/// <param name="section"></param>
/// <returns></returns>
private bool GetSection(string section)
{
try
{
// Does the Section Exist
queryString = "/configuration/" + section;
node = root.SelectSingleNode(queryString);
if (node != null)
return (true);

// Get the Configuration Node
queryString = "/configuration";
node = root.SelectSingleNode(queryString);
if (node != null)
{
// Create a New Section
StringBuilder sb = new StringBuilder(1000);
sb.Append("<"); sb.Append(section); sb.Append(">");
sb.Append("</"); sb.Append(section); sb.Append(">");

node.InnerXml += sb.ToString();
return (true);
}
}
catch (Exception)
{
// Nothing to do
}

// Error Occurred
return (false);
}
#endregion

#endregion

} // Class
}

Nov 12 '05 #1
2 10367
"David Elliott" <We*****@newsgroups.nospam> wrote in message news:2b********************************@4ax.com...
I am looking to see if there is a better way to add a
new node / attribute than using XmlDocument.InnerXml. : : but couldn't really see another way of doing this without
defining namespaces and the like.
The example XML you've given doesn't contain any namespaces,
so why should you define one?

Have a look at the CreateElement() and CreateAttribute()
methods of XmlDocument, and then AppendChild() on XmlNode
(and remember that XmlDocument is an XmlNode, so it also
allows you to AppendChild() nodes to it).
the lines that I am wondering about are lines: 79, 227,
and 266

79: xmlDoc.InnerXml = "<?xml version=\"1.0\" encoding=\"utf-8\"?><configuration></configuration>";

If you set UTF-8 Encoding on an I/O Stream wrapped by an
XmlTextWriter (or TextWriter), this XML declaration will
be emitted for you automatically.

Here's how you'd create a custom XmlDeclaration for the
XmlDocument (note that if you do Save this XML to a
TextWriter-based class, its Encoding takes precedence).

XmlDeclaration xmlDecl = xmlDoc.CreateXmlDeclaration("1.0", "utf-8", "");

Then you'd want to create your <configuration> element.

XmlElement eRoot = xmlDoc.CreateElement( "configuration");

Finally, add the root element to XmlDocument and insert
the XmlDeclaration before it,

xmlDoc.AppendChild( eRoot);
xmlDoc.InsertBefore( xmlDecl, eRoot);
: :
223: StringBuilder sb = new StringBuilder(500);
224: sb.Append("<add key=\""); sb.Append(key); sb.Append("\" ");
225: sb.Append("value=\""); sb.Append(keyValue); sb.Append("\" />");
226:
227: node.InnerXml += sb.ToString();

XmlElement eAdd = xmlDoc.CreateElement( "add");
eAdd.SetAttribute( "key", key);
eAdd.SetAttribute( "value", keyValue);
node.AppendChild( eAdd);
: :
264: sb.Append("</"); sb.Append(section); sb.Append(">");
265:
266: node.InnerXml += sb.ToString();

Your example code never gives a value to the argument,
section, but from your example XML I'll guess it's
<appSettings> (although I don't see where you have
inserted the child node between the start and end
elements).
XmlElement eAppSettings = xmlDoc.CreateElement( "appSettings");
eAppSettings.AppendChild( eAdd);
eRoot.AppendChild( eAppSettings);
These three statements essentially tie together the
entire configuration document's XML nodes.

It looks like you own (because you want to own?) the
entire configuration file, but I'll also point out that
in the .NET Framework's System.Configuration namespace
are classes automatically supporting this configuration
schema to read a config file from "application.exe.config"
or "web.config".

Using the built-in configuration file support allows you
to create the element,

<add name="key" value="keyValue" />

in a single statement like this,

ConfigurationSettings.AppSettings[ key] = keyValue;

with the default NameValueSectionHandler.

Derek Harmon
Nov 12 '05 #2
Thanks,
Dave

"Derek Harmon" wrote:
"David Elliott" <We*****@newsgroups.nospam> wrote in message news:2b********************************@4ax.com...
I am looking to see if there is a better way to add a
new node / attribute than using XmlDocument.InnerXml.

: :
but couldn't really see another way of doing this without
defining namespaces and the like.


The example XML you've given doesn't contain any namespaces,
so why should you define one?

Have a look at the CreateElement() and CreateAttribute()
methods of XmlDocument, and then AppendChild() on XmlNode
(and remember that XmlDocument is an XmlNode, so it also
allows you to AppendChild() nodes to it).
the lines that I am wondering about are lines: 79, 227,
and 266

79: xmlDoc.InnerXml = "<?xml version=\"1.0\" encoding=\"utf-8\"?><configuration></configuration>";

If you set UTF-8 Encoding on an I/O Stream wrapped by an
XmlTextWriter (or TextWriter), this XML declaration will
be emitted for you automatically.

Here's how you'd create a custom XmlDeclaration for the
XmlDocument (note that if you do Save this XML to a
TextWriter-based class, its Encoding takes precedence).

XmlDeclaration xmlDecl = xmlDoc.CreateXmlDeclaration("1.0", "utf-8", "");

Then you'd want to create your <configuration> element.

XmlElement eRoot = xmlDoc.CreateElement( "configuration");

Finally, add the root element to XmlDocument and insert
the XmlDeclaration before it,

xmlDoc.AppendChild( eRoot);
xmlDoc.InsertBefore( xmlDecl, eRoot);
: :
223: StringBuilder sb = new StringBuilder(500);
224: sb.Append("<add key=\""); sb.Append(key); sb.Append("\" ");
225: sb.Append("value=\""); sb.Append(keyValue); sb.Append("\" />");
226:
227: node.InnerXml += sb.ToString();

XmlElement eAdd = xmlDoc.CreateElement( "add");
eAdd.SetAttribute( "key", key);
eAdd.SetAttribute( "value", keyValue);
node.AppendChild( eAdd);
: :
264: sb.Append("</"); sb.Append(section); sb.Append(">");
265:
266: node.InnerXml += sb.ToString();

Your example code never gives a value to the argument,
section, but from your example XML I'll guess it's
<appSettings> (although I don't see where you have
inserted the child node between the start and end
elements).
XmlElement eAppSettings = xmlDoc.CreateElement( "appSettings");
eAppSettings.AppendChild( eAdd);
eRoot.AppendChild( eAppSettings);
These three statements essentially tie together the
entire configuration document's XML nodes.

It looks like you own (because you want to own?) the
entire configuration file, but I'll also point out that
in the .NET Framework's System.Configuration namespace
are classes automatically supporting this configuration
schema to read a config file from "application.exe.config"
or "web.config".

Using the built-in configuration file support allows you
to create the element,

<add name="key" value="keyValue" />

in a single statement like this,

ConfigurationSettings.AppSettings[ key] = keyValue;

with the default NameValueSectionHandler.

Derek Harmon

Nov 12 '05 #3

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

3
by: Anita C | last post by:
I have the foll. code to update the value of an attribute: xmlDocument.Load("abc.xml"); XmlAttribute xmlAttrib = xmlDocument.SelectSingleNode(root/web/theme/@desc); xmlAttrib.Value =...
0
by: Robert Bruce | last post by:
Hello, I'm trying to round-trip some XML out of Adobe InDesign, through my application and then back into InDesign. Tables in InDesign are created using a specific namespace like this: ...
1
by: BJ Allmon | last post by:
I'm new to the .NET community. My name is BJ and I've been developing web applications for years now. I'm very new to .NET and could use some assistance. I don't think I'm asking for very much...
0
by: mortb | last post by:
My problem is with a XML file that resides on my windows 2003 web server. I have this user control which I include on every page in my applicaiton. The control makes it possible for the users to...
2
by: Paul | last post by:
Is there a way to test if an XmlNode represents an enum?
3
by: Andy | last post by:
Hello Guys: What am I doing wrong with this code? I can't seem to get it to simply add an attribute to my node. The node already exists. I am simply opening the XMLDocument and creating one...
5
by: MaxMax | last post by:
If I have an XmlNode/XmlAttribute and I want to convert its value to a "native" c# type (for example boolean), how should I do? I can't (for example) simply use Boolean.TryParse, because Xml...
7
by: Peter Bradley | last post by:
Hi, First of all, a confession. This is a cross post from the microsoft.public.dotnet.general list. I posted there not realising that this list existed. Apologies to those who read both...
4
by: CSharper | last post by:
I am reading an XmlFile using XmlDocument and traverse through the XmlNode, as I read I need to append an attribute to the XmlNode on some conditions. I tried xmlNode.Attributes.Append() It...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.