Click here to Skip to main content
Rate this: bad
good
Please Sign up or sign in to vote.
See more: C#
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 13-Apr-11 2:49am
Edited 13-Apr-11 2:53am
Tarun.K.S41.9K
v3
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 1

Here is how it will work :
 
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! Smile | :)
 
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 :
 
            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.
                    }
                }
            }
Frown | :(
 
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!
  Permalink  
v4
Comments
SAKryukov at 13-Apr-11 9:47am
   
You apparently loading the whole document, not what OP wanted. (The question is bad.) --SA
Tarun.K.S at 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.
SAKryukov at 13-Apr-11 14:31pm
   
Not in the nearest future, will be busy. May be later... --SA
Tarun.K.S at 13-Apr-11 14:35pm
   
Ohkay no problem.
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 2

Hi
Muhammadhussain,
 
Please do the following steps:
 
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
  Permalink  
Comments
Tarun.K.S at 13-Apr-11 9:14am
   
It would be better to use the XPath.
SAKryukov at 13-Apr-11 9:48am
   
You apparently loading the whole document, not what OP wanted. (The question is bad.) --SA
Tarun.K.S at 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
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 3

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.
  Permalink  
v2
Comments
Tarun.K.S at 13-Apr-11 14:32pm
   
By flat file you mean reading as txt?
Nishant Sivakumar at 13-Apr-11 14:36pm
   
In this specific case yeah he can read it as text, not a requirement though.
Tarun.K.S at 13-Apr-11 14:38pm
   
I was thinking of using XmlTextWriter but AFAIK it can't modify the elements or am I missing something?
Nishant Sivakumar at 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 at 13-Apr-11 14:52pm
   
Hmmm it seems a bit tricky.
Nishant Sivakumar at 13-Apr-11 14:54pm
   
Of course it is :-) That's because the requirement is tricky too.
Tarun.K.S at 13-Apr-11 15:01pm
   
That's right!
muhammadhussain at 14-Apr-11 2:15am
   
So far i am using the var query=(from waypoint In xdocument.load(filePath).descendants("waypoint").asEnumerable() where wayoint.attribute("a").value="2" select waypoint).firstorDefault() It is woking fine but , My problem is to update the fetched waypoints values in the xml file.
Tarun.K.S at 14-Apr-11 3:37am
   
I have did that in my answer if you can check please. Also you mentioned you don't want to load the whole document and but you are doing it here. Make up your mind.
muhammadhussain at 15-Apr-11 1:50am
   
In my case "how whole xml will be loaded "? As it is just a query which returns the result and the result will be loaded into memory. Do you know how to write a specific element at a particular index in the xml onto disk?
Tarun.K.S at 15-Apr-11 2:57am
   
In your query, XDocument.Load(filePath) loads the whole Document in the memory. The result is also stored in the memory but thats the great feature of LINQ.
Tarun.K.S at 15-Apr-11 9:46am
   
I have updated the answer. Try the new solution.

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

  Print Answers RSS
Your Filters
Interested
Ignored
     
0 Shai Vashdi 1,010
1 OriginalGriff 447
2 Manas Bhardwaj 378
3 Tadit Dash 330
4 Damith Weerasinghe 320
0 Sergey Alexandrovich Kryukov 9,625
1 OriginalGriff 6,065
2 Peter Leow 4,500
3 Maciej Los 3,565
4 Abhinav S 3,513


Advertise | Privacy | Mobile
Web03 | 2.8.140415.2 | Last Updated 15 Apr 2011
Copyright © CodeProject, 1999-2014
All Rights Reserved. Terms of Use
Layout: fixed | fluid