How to update attribute of xml based on textbox value in C# - c#

I will appreciate your help with this one.
I've written a code to enable me to modify the attribute of an xml element based on the value in the textbox.
Everything seems to work when debugged, but upto the last code, as the xml file deos not get updated. What am I doing wrong?
private void btnUpdate_Click(object sender, EventArgs e)
{
XmlDocument doc = new XmlDocument();
doc.PreserveWhitespace = true;
doc.Load("Info.xml");
XmlNamespaceManager ns = new XmlNamespaceManager(doc.NameTable);
ns.AddNamespace("root", doc.DocumentElement.NamespaceURI);
XmlNode Body = doc.SelectSingleNode("//root:Body", ns);
ns.AddNamespace("child", Body.FirstChild.NextSibling.NamespaceURI);
XmlNode nodeIr = doc.SelectSingleNode("//child:Name", ns);
nodeIr.InnerText = txtBox1.Text;
doc.Save("Info.xml");
}
I believe the last line needs to be modified.
Thank you

Related

Null return on XmlDocument.SelectSingleNode through valid xpath (did try the old answer)

I've read the other question and apply the answer to my code, but it still doesn't work.
I use xml to read the csproj file to read/write something into it body.
This is my csproject file if anyone care!
My code:
static void Main(string[] args)
{
string file = #"D:\Project\svn_longnx\LearnSvnRevision\ConsoleApp1\WindowsFormsApp1\WindowsFormsApp1.csproj";
XmlDocument xdoc = new XmlDocument();
xdoc.Load(file);
XmlNamespaceManager nsmgr = new XmlNamespaceManager(xdoc.NameTable);
nsmgr.AddNamespace("default", "http://schemas.microsoft.com/developer/msbuild/2003");
XmlElement root = xdoc.DocumentElement;
XmlNode node = root.SelectSingleNode("Project/PropertyGroup/ApplicationVersion",nsmgr);
Console.WriteLine(node.Value);
}
This dummy code failed either:
static void Main(string[] args)
{
string file = #"D:\Project\svn_longnx\LearnSvnRevision\ConsoleApp1\WindowsFormsApp1\WindowsFormsApp1.csproj";
XmlDocument xdoc = new XmlDocument();
xdoc.Load(file);
XmlElement root = xdoc.DocumentElement;
XmlNode node = root.SelectSingleNode("Project/PropertyGroup/ApplicationVersion");
Console.WriteLine(node.Value);
}
It's much easier to use XDocument and associated objects instead of the older XmlDocument bits. Also, you're probably falling down because of namespaces. Instead, try this code:
var doc = XDocument.Load(#"D:\Project\svn_longnx\Lear...\WindowsFormsApp1.csproj");
var ns = XNamespace.Get("http://schemas.microsoft.com/developer/msbuild/2003");
var applicationVersionElements = doc.Element(ns + "Project")
.Descendants(ns + "PropertyGroup")
.Descendants(ns + "ApplicationVersion");
foreach (var element in applicationVersionElements)
{
Console.WriteLine(element.Name);
}
This is just one way as an example of how to get that specific element to demonstrate how easy it is to use.
Note, you may need to add using System.Xml.Linq;

C# .Net XML - Object reference not set to an instance of an object - writing value to XML

I am trying to write something to xml file. I have a function:
bool WriteValueTOXML(string pstrValueToRead, string pstrValueToWrite)
{
try
{
XmlTextReader reader = new XmlTextReader("config.ini");
XmlDocument doc = new XmlDocument();
doc.Load(reader);
reader.Close();
XmlNode oldNode;
XmlElement root = doc.DocumentElement;
oldNode = root.SelectSingleNode(#"/settings/" + pstrValueToRead);
oldNode.InnerText = pstrValueToWrite;
doc.Save("config.ini");
return true;
}
catch (NullReferenceException e)
{
MessageBox.Show(e.Message);
return false;
}
}
When I am trying to set InnerText in oldNode (oldNode.InnerText = pstrValueToWrite;) the NullReferenceException is thrown with message "Object reference not set to an instance of an object".
File that I am trying to write to is here:config.ini
oldNode = root.SelectSingleNode(#"/settings/" + pstrValueToRead); must be returning null. Put a break point just after that line of code and check if that's the case. If so, adjust your xpath so it returns an actual node.
This example works with the below assumptions:
XmlDocument doc = new XmlDocument();
using(XmlTextReader reader = new XmlTextReader(#"C:\Temp\config.ini"))
{
doc.Load(reader);
}
XmlElement root = doc.DocumentElement;
XmlNode oldNode = root.SelectSingleNode(#"/settings/database");
oldNode.InnerText = "Blah Blah2";
doc.Save(#"C:\Temp\config.ini.out");
This is assuming you want to update the inner text your path to database of the database tag to something else.

Method is executed but not has effect

I'm creating a class for manipulate XML, I created overload of my method RemoveNode
public partial class HWXml
{
public string XmlFile;
private XmlDocument XmlDoc = new XmlDocument();
public HWXml(string XmlFile)
{
this.XmlFile = XmlFile;
}
public XmlNode SelectSingleNode(string NodePath)
{
XmlDoc.Load(XmlFile);
return XmlDoc.SelectSingleNode(NodePath);
}
public void RemoveNode(XmlNode removeChild)
{
XmlDoc.Load(XmlFile);
removeChild.ParentNode.RemoveChild(removeChild);
XmlDoc.Save(XmlFile);
}
public void RemoveNode(string RemoveChild)
{
XmlDoc.Load(XmlFile);
XmlNode removeChild = XmlDoc.SelectSingleNode(RemoveChild);
removeChild.ParentNode.RemoveChild(removeChild);
XmlDoc.Save(XmlFile);
}
}
When I try remove node using string parameter, it works
private void RemoveXML_Click(object sender, RoutedEventArgs e)
{
MyXmlClass myXmlClass = new MyXmlClass(XmlFile);
myXmlClass.RemoveNode("root/Content");
}
But when I try remove node using XmlNode parameters, it will compile, execute, no error message, but no effect, it no remove nothing in the XML file.
private void RemoveXML_Click(object sender, RoutedEventArgs e)
{
MyXmlClass myXmlClass = new MyXmlClass(XmlFile);
XmlNode node = myXmlClass.SelectSingleNode("root/Conteudo");
myXmlClass.RemoveNode(node);
}
What is problem?
XmlNode parameter is definitely not part of XmlDoc which you are loading inside this method (because you have this node before document is loaded). Thus manipulations on this node do not affect document which node does not belong to.
In second case you are selecting node of document which was loaded. This node belongs to xml tree which was just loaded into XmlDoc, thus removing node affects document.
What you should understand is how XmlDocument (same for XDocument) is loaded:
If it has some nodes (previously loaded) then all nodes are removed
XmlReader created
This reader reads input stream node by node
For each found node, new instance of appropriate class is created and added to document (e.g. if reader has read some element, then new XmlElement is created and added to current element of document)
So, you end up with graph of completely new objects which have no relation to objects which was created during previous load of xml. After loading xml, instance of XmlDocument stays same, but it has completely new objects inside.

XmlDocument Save keeps file open

I have a simple c# function that creates a basic XML file and saves:
private void CreateXMlFile(string Filename, string Name, string Company)
{
XmlDocument doc = new XmlDocument();
XmlNode docNode = doc.CreateXmlDeclaration("1.0", "UTF-8", null);
doc.AppendChild(docNode);
XmlNode licenseNode = doc.CreateElement("license");
doc.AppendChild(licenseNode);
XmlNode node = doc.CreateElement("Name");
node.AppendChild(doc.CreateTextNode(Name));
licenseNode.AppendChild(node);
node = doc.CreateElement("Company");
node.AppendChild(doc.CreateTextNode(Company));
licenseNode.AppendChild(node);
doc.Save(Filename);
}
When I try to edit or delete the file I always get following error:
The process cannot access the file because it is being used by another
process.
XmlDocument doesnt have any inbuilt dispose or close routines and wondered how I can force the file to close before later editing or deleting it.
I have tried to save the file using StreamWriter:
StreamWriter outStream = System.IO.File.CreateText(outfile);
outStream.Write(data);
outStream.Close();
But this didnt make a difference with the same error.
Your advice is greatly accepted.
Thank you
Send Stream to XmlDocument's Save method instead of file name.
private static void Main(string[] args)
{
CreateXMlFile("c:\\test.xml", "testName", "testCompany");
}
private static void CreateXMlFile(string Filename, string Name, string Company)
{
XmlDocument doc = new XmlDocument();
XmlNode docNode = doc.CreateXmlDeclaration("1.0", "UTF-8", null);
doc.AppendChild(docNode);
XmlNode licenseNode = doc.CreateElement("license");
doc.AppendChild(licenseNode);
XmlNode node = doc.CreateElement("Name");
node.AppendChild(doc.CreateTextNode(Name));
licenseNode.AppendChild(node);
node = doc.CreateElement("Company");
node.AppendChild(doc.CreateTextNode(Company));
licenseNode.AppendChild(node);
StreamWriter outStream = System.IO.File.CreateText(Filename);
doc.Save(outStream);
outStream.Close();
}
I tried executing above code and it is working fine at my end.
Your code is fine. I tested it on my machine and there is no lock left after Save().
Try to use Unlocker (http://www.softpedia.com/get/System/System-Miscellaneous/Unlocker.shtml) to check whether you are really the one who holds the lock.
Which .NET framework do you use? Theres also a report (http://bytes.com/topic/net/answers/467028-xmldocument-save-does-not-close-file-properly) which was not reproducable too.

ASP.net load XML file from URL

Trying to just simply parse an XML file;
protected void Page_Load(object sender, EventArgs e)
{
XmlDocument xdoc = new XmlDocument();//xml doc used for xml parsing
xdoc.LoadXml("http://latestpackagingnews.blogspot.com/feeds/posts/default");//loading XML in xml doc
XmlNodeList xNodelst = xdoc.DocumentElement.SelectNodes("entry");//reading node so that we can traverse thorugh the XML
foreach (XmlNode xNode in xNodelst)//traversing XML
{
litFeed.Text += "read";
}
}
But I get:
Data at the root level is invalid.
Line 1, position 1.
Do I have to do an XMLHTTP request to the file first? Or am I right to assume I can load it in from an external url?
try this :
protected void Page_Load(object sender, EventArgs e)
{
XmlDocument xdoc = new XmlDocument();//xml doc used for xml parsing
xdoc.Load(
"http://latestpackagingnews.blogspot.com/feeds/posts/default"
);//loading XML in xml doc
XmlNodeList xNodelst = xdoc.DocumentElement.SelectNodes("entry");//reading node so that we can traverse thorugh the XML
foreach (XmlNode xNode in xNodelst)//traversing XML
{
litFeed.Text += "read";
}
}
LoadXml is waiting for an xml string directly, where Load can use an uri to grab the xml data. With your code, the xml parser was actually trying to parse the adress as xml, not the content at the uri location.
[Edit] you may take a look at the builtin feed processing classes of the .Net Framework. These classes are in the System.ServiceModel.Syndication namespace. They can to the parsing job for you quite easily.

Categories