Click here to Skip to main content
15,887,585 members
Please Sign up or sign in to vote.
3.33/5 (3 votes)
See more:
Hi Codians,
I am facing an issue from couple of days ago;
My scenario is as,
I want to load the particular element from the xml file for a particular value and then to change the value and to write it in the xml file in the place fetched element index.
I am wondering how it will be possible? I have posted threads in the asp.net forum and stackoverflow as well but still i am in the search of the solution for this issue.
<gpx>
    <waypoints>
      <waypoint a="3">
        <name>name of waypoint</name>
        <description> dscrtiption</description>
     </waypoint>
     <waypoint a="2">
       <name>second waypoint</name>
       <description/>
     </waypoint>
   </waypoints>
</gpx>

What I am trying is to load only the waypoint whose a="2", and to change its name value from "second waypoint" to "something" and to replace the waypoint a="2" to new waypoint whose name value will be "something" in the xml file onto disk.
Thanks
Posted
Updated 13-Apr-11 2:53am
v3

Here is how it will work :

MSIL
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(@"C:\Well.xml");
XmlNode node = xmlDoc.SelectSingleNode("/gpx/waypoints/waypoint[@a='2']/name");
node.InnerText = "Something";
xmlDoc.Save(@"C:\Well.xml");


Hope it helped! :)

Update 1:
From the subject of your question, it seems that you don't want to load the whole XML.
Well there is a class XmlTextWriter which is a stream-based loading of XML and it won't load the whole XML. It will read node by node, in contrast to XmlDocument which is a in-memory based loading of XML, it loads the whole XML into memory.

Now coming back to the point, after searching for more info on the internet, it was just like I thought, XmlTextWriter cannot modify the Xml nodes. So your solution will be to use the XmlDocument itself for Modifying the nodes.

I did however tried in this way :

C#
XmlTextReader reader = new XmlTextReader(path);
while (reader.Read())
{
    if (reader.NodeType == XmlNodeType.Element && reader.Name == "waypoint")
    {
        if (reader.GetAttribute("a") == "2")
        {
            XmlDocument xmlDoc = new XmlDocument();
            xmlDoc.LoadXml(reader.ReadOuterXml());
            XmlNode node = xmlDoc.SelectSingleNode(".");
            //String str = node.InnerText;
            node.InnerText = "Something";
            //The above statement gave this error : Object reference not set to an instance of an object.
        }
    }
}

:(

So it didn't work for me.
I will still try to figure out a solution for this.

Update 2:

Found some articles in CodeProject. According your requirements, check these :

-First you can split your large xml file into smaller ones. Check this article : http://www.codeproject.com/KB/XML/SplitLargeXMLintoSmallFil.aspx#xx2994884xx[^]

- After finding the node, load the smaller XML into an XmlDocument and then edit like I did in my solution. Then merge the xml files like mentioned in this article : http://www.codeproject.com/KB/XML/XStreamingElement_Merge.aspx[^]

Try it out. Good luck!
 
Share this answer
 
v4
Comments
Sergey Alexandrovich Kryukov 13-Apr-11 9:47am    
You apparently loading the whole document, not what OP wanted.
(The question is bad.)
--SA
Tarun.K.S 13-Apr-11 14:06pm    
I tried to do it but got stuck! If you can help me figure it out. I have updated the answer.
Sergey Alexandrovich Kryukov 13-Apr-11 14:31pm    
Not in the nearest future, will be busy.
May be later...
--SA
Tarun.K.S 13-Apr-11 14:35pm    
Ohkay no problem.
Hi Muhammadhussain,

Please do the following steps:

C#
XmlDocument doc = new XmlDocument();
doc.LoadXml("Path.xml");
XmlElement root = doc.DocumentElement;

for (int n = 0; n < doc.DocumentElement.ChildNodes[0].ChildNodes.Count; n++)
{
    XmlNodeList waypoint = doc.DocumentElement.ChildNodes[0].ChildNodes[n];
    for(int w = 0; w < waypoint.Count; w++)
    {
        string waypointAttribute = waypoint.Attributes["a"].Value;
        if(waypointAttribute == "2")
        {
            waypoint.Attributes["name"] = "somthing";
        }
    }
}
doc.Save("Path.xml");


Thanks,
Imdadhusen
 
Share this answer
 
Comments
Tarun.K.S 13-Apr-11 9:14am    
It would be better to use the XPath.
Sergey Alexandrovich Kryukov 13-Apr-11 9:48am    
You apparently loading the whole document, not what OP wanted.
(The question is bad.)
--SA
Tarun.K.S 14-Apr-11 8:58am    
Comment from OP :

Hi ImdadHusen,

I have tried the solution2, but it also loads the whole xml document.
What I trying is to load only the particular waypoint whose attribute a="2".
Then change the value of name element of waypoint and to write the modified waypoint in the xml on disk. It should also be sure that the updated waypoint should replaced the old waypoint.

Thanks
What you are trying to do is kinda unrealistic, but if there's a way to do it as you wish to, treat the file as a flat file. Instead of treating it as an XML document to parse, open the file as a flat file, read chunks of data, and make heuristic guesses as to how many bytes you need to skip or read ahead to hit the area you want to modify. And once you hit the data you need to change, modify it, and write it back to the file, and exit. It'll be a fair bit of work trying to locate the data while also trying to make sure you have minimal number of read-aheads but it's a workable solution.
 
Share this answer
 
v2
Comments
Tarun.K.S 13-Apr-11 14:32pm    
By flat file you mean reading as txt?
Nish Nishant 13-Apr-11 14:36pm    
In this specific case yeah he can read it as text, not a requirement though.
Tarun.K.S 13-Apr-11 14:38pm    
I was thinking of using XmlTextWriter but AFAIK it can't modify the elements or am I missing something?
Nish Nishant 13-Apr-11 14:44pm    
Uhm no, I was not suggesting using any kind of XML class. Just open the file for read/write and heuristically locate the area you want to modify, and then write back. The trick here is to make sure the changed data is of the same length as the original data. If the new data's length differs, then you have to write back the rest of the file too.
Tarun.K.S 13-Apr-11 14:52pm    
Hmmm it seems a bit tricky.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900