1

Hi i have the following code to read the xml file and change the value of particular node ,but i want to do the same using xmltextreader or xmlreader, i am trying to avoid the statement doc.Save(System.Web.HttpContext.Current.Server.MapPath("Data/Example.xml")); , which has a direct reference to my physical file.

XmlDocument doc = new XmlDocument();
                   string xmlFile = System.Web.HttpContext.Current.Server.MapPath("Data/Example.xml");
                   doc.Load(xmlFile);
                   XmlNodeList xmlnode = doc.GetElementsByTagName("value");
                   xmlnode[0].ChildNodes[0].Value = 23;
 doc.Save(System.Web.HttpContext.Current.Server.MapPath("Data/Example.xml"));
mahesh
  • 3,067
  • 16
  • 69
  • 127
  • +1 but question anyway looks unconcius, it's impossible to *save* anything using *reader*, is reminds me for a bad knowledge of english language of mine. – Alan Turing Sep 15 '11 at 06:31

2 Answers2

2

Well something's going to have to have a reference to the file. However, you could easily change your code to simply accept a Stream (which would have to be readable, writable and seekable):

private static void ChangeDocument(Stream stream)
{
    XmlDocument doc = new XmlDocument();
    doc.Load(stream);
    XmlNodeList xmlnode = doc.GetElementsByTagName("value");
    xmlnode[0].ChildNodes[0].Value = 23;
    stream.Position = 0;
    doc.Save(stream);
    stream.SetLength(stream.Position); // Truncate the file if it was longer
}

It's somewhat ugly, admittedly...

Of course you could always pass in the filename itself - your MapPath call would still be in a higher level method, which may be all you're trying to achieve:

private static void ChangeDocument(string filename)
{
    XmlDocument doc = new XmlDocument();
    doc.Load(filename);
    XmlNodeList xmlnode = doc.GetElementsByTagName("value");
    xmlnode[0].ChildNodes[0].Value = 23;
    doc.Save(filename);
}

One final aside - if you're using .NET 3.5 or higher, I'd strongly recommend using LINQ to XML as a rather nicer XML API.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • Tricky way to hide doc.Save(...)? – Alan Turing Sep 15 '11 at 06:25
  • Then full path to a file will be in another code where you declare Stream object, anyway, it's simply unavoidable using file-based approach – Alan Turing Sep 15 '11 at 06:26
  • @Artur: Yes, if you want to access a file, you're going to need the name to be known *somewhere*. I assumed that the OP didn't want it to be computed *here*, which may well be entirely reasonable. (For example, this code could be put into a class libraries used in several applications, where `Server.MapPath` may well be inappropriate.) – Jon Skeet Sep 15 '11 at 06:31
  • Is it really necessary to have doc.Save, can i update my xml file with any other good approach? – mahesh Sep 15 '11 at 06:36
  • 1
    @mahesh: Well something's got to know how to write back to the file. You could pass in a `Func` - or if you're happy to write to a *different* file, you could pass in an `XmlWriter` to start with. It would help if you'd say *exactly* what you're trying to avoid here. Why do you dislike `doc.Save`? – Jon Skeet Sep 15 '11 at 06:39
  • No i just wanted to change my code to implement the following approach,byte[] bytes = Encoding.ASCII.GetBytes(dataXml); dataStream = new MemoryStream(bytes); //Create Xmlreader from memory stream XmlReader reader = XmlReader.Create(dataStream); XElement data = XElement.Load(reader); – mahesh Sep 15 '11 at 06:50
  • @mahesh: But *why* did you want to do that? Using XmlReader is much harder, and you'll need some way of reflecting the changes. You also shouldn't assume that an XML file is in ASCII - you shouldn't even assume it's in UTF-16. Admittedly in this case you may know it, but it still makes the code more brittle. – Jon Skeet Sep 15 '11 at 06:55
  • Thanks for the usefull reply, i completly agree with you, in the code sample specified by you ,can you please show, how to create stream and pass that to ChangeDocument(Stream stream) function – mahesh Sep 15 '11 at 07:02
  • @mahesh: Just use `File.Open(path, FileMode.Open)`. – Jon Skeet Sep 15 '11 at 07:11
  • I am planning to use Linq to xml – mahesh Sep 15 '11 at 07:11
  • Can you please suggest me some good article in linq to xml , for the functionality which i am trying to implement – mahesh Sep 15 '11 at 07:26
  • @mahesh: I would just find some LINQ to XML tutorials - there are *loads* all over the web. – Jon Skeet Sep 15 '11 at 08:22
1

You can not write or update XML data using XmlTextReader or XmlReader ansectors, use XmlTextWriter or XmlWriter ancestors, ot XmlSerializer.Serialize(..) method as alternative.

You can not avoid the statement and alike,

doc.Save(System.Web.HttpContext.Current.Server.MapPath("Data/Example.xml"));

which has a direct reference to your physical file, because you have to write the changed nodes back to the origin file again, otherwize you have to switch your system from using file-based approach (ASP.NET web site using file-based data storage) to database-driven approach (ASP.NET web site using the database server).

As alternative, use your own XML data in your SQL server, then load and update it using EF of ORM.

Alan Turing
  • 2,482
  • 17
  • 20