开发者

How to append data to XML file using C#

I have a image loaded in a picture box.When i click on the image there is some data(not required here) which will be stored in an XML file.But the problem is when ever i click the mouse on image, the data is getting over written.Instead i need to add the data that is obtained after every mouse click.here is m开发者_JS百科y part of the program under MouseClick event.

private void pictureBox1_MouseClick(object sender, MouseEventArgs e)
{            
    float u = l[p + 1] - l[p];
    float v = m[p + 1] - m[p];
    float w = (e.Y - m[p]) / v; //subtract from latitude
    float z = (e.X - l[p]) / u; //add to longitude.
    float latmin = h[p] - w;
    float longmin = j[p] + z;

    A1 = e.X - c[p];
    A2 = e.Y - d[p];
    B1 = c[p + 1] - c[p];
    B2 = d[p + 1] - d[p];
    A = Math.Sqrt(Math.Pow(A1, 2) + Math.Pow(A2, 2));
    B = Math.Sqrt(Math.Pow(B1, 2) + Math.Pow(B2, 2));
    dotproduct = A1 * B1 + A2 * B2;
    theta = (180 / Math.PI) * Math.Acos( dotproduct / (A * B));
    if (e.X < c[p])
    {
        theta1 = 360 - theta;
    }
    else
    {
        theta1 = theta;
    }

    MessageBox.Show(string.Format(" Latitude:{0}°{1:0.0}'\n Longitude:{2}°{3:0.0}' \n ICAO LOC: {4} {5}", g[p] + (int)latmin / 60, latmin % 60, i[p] + (int)longmin / 60, longmin % 60, textBox1.Text, Math.Abs((int)theta1)));

    using (XmlWriter writer = XmlWriter.Create(string.Format("{0}.xml", textBox2.Text)))
    {
        writer.WriteStartDocument();
        writer.WriteStartElement("WayPoints");

         writer.WriteStartElement("Latitude");
         writer.WriteElementString("Degrees",XmlConvert.ToString( g[p] + (int)latmin / 60));
         writer.WriteElementString("Minutes", XmlConvert.ToString(latmin % 60));
         writer.WriteEndElement();

        writer.WriteStartElement("Longitude");
        writer.WriteElementString("Degrees", XmlConvert.ToString(i[p] + (int)longmin / 60));
        writer.WriteElementString("Minutes", XmlConvert.ToString(longmin % 60));
        writer.WriteEndElement();

        writer.WriteStartElement("IcaoLocator");
        writer.WriteElementString("Type", textBox1.Text);
        writer.WriteElementString("Angle", XmlConvert.ToString(Math.Abs((int)theta1)));
        writer.WriteEndElement();

        writer.WriteEndElement();
        writer.WriteEndDocument();
    }
}

The file name of the XML is taken from the text in the textbox2.

Please give me some suggestion ,such that i can store data of all mouseclicks in one file.


use the include features of xml.

The idea is to have one "master" file that holds the document declaration, and a "child" file that holds the inner nodes. In this case, you can simply append text to the child file, and the master will remain valid.

master.xml file :

<?xml version="1.0"?>

<WayPoints xmlns:xi="http://www.w3.org/2001/XInclude">
    <xi:include href="slave.xmlpart"/>
</WayPoints>

slave.xmlpart :

<WayPoint>
    <Latitude>
      <Degrees>1</Degrees>
    </Latitude>
    <Longitude>
      <Degrees>1</Degrees>
    </Longitude>
</WayPoint>
<WayPoint>
    <Latitude>
      <Degrees>2</Degrees>
    </Latitude>
    <Longitude>
      <Degrees>2</Degrees>
    </Longitude>
<WayPoint>

This will allow you to benefits both the Xml standard, and the perf of text writing. Only, you have to use File.AppendText, instead of XmlWriter class, to be able to works with slave file. You could, if you still want to use XmlWriter, use a temp MemoryStream where you build the nodes, before appending the content of the stream to the slave file.

[Edit] here is a sample code :

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Xml.Linq;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            EnsureFiles();
            Console.WriteLine("Press espace to quit");
            ConsoleKeyInfo key;
            do
            {
                key = Console.ReadKey();
                Append(key);
            }
            while (key.Key != ConsoleKey.Escape);

            Console.ReadLine();
        }

        private static void Append(ConsoleKeyInfo key)
        {
            var keyEvent = new XElement("KeyEvent",
                new XElement("Key", new XAttribute("key", key.Key.ToString())), 
                new XElement("At", DateTime.Now.ToString())
                );
            File.AppendAllText("slave.xmlpart", keyEvent.ToString());
        }

        private static void EnsureFiles()
        {
            if (!File.Exists("slave.xmlpart"))
            {
                File.WriteAllText("slave.xmlpart", ""); // simply create the file
            }
            if (!File.Exists("master.xml"))
            {
                var doc = new XDocument(
                    new XElement("WayPoints",
                        new XElement("{http://www.w3.org/2001/XInclude}include",
                            new XAttribute("href", "slave.xmlpart")
                            )
                    )
                );
                doc.Save("master.xml");
            }
        }
    }
}

However, it seems that the Xdocument class does not follow includes, but this article shows a solution : http://www.catarsa.com/Blog/Kohler-Radim/2010/5/Linq-To-Xml-XInclude


I will use an instance of XmlDocument inside the class, and append to it the proper nodes at any mouse click. You can save the doc on disk each time ( not so efficient, but you will not notice any performance decrease if file is not huge ) or delay the save in some other cirumstance ( explicit button, or window close )


You could look at using XDocument which is part of the System.Xml.Linq namespace. This form of XML document gives you a much easier API to reading and amending XML Docs, utilizing common liq functionality. Here's a MSDN link which details it.

To add a node you can do the following:

XDocument xmlDocument = XDocument.Load("FilePath");
XElement parentNode = xmlDocument.Root.Element("ParentNode");
XElement node = new XElement("NodeName"); 
parentNode.Add(node);
xmlDocument.Save("FilePath");

That is a simple example and is not implementing any null checks and is assuming that the parent node only has one instance.

Hope that helps.

Paul

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜