0

リストのデータを XML ファイルに保存する次のコードがありますが、リストに 2 番目のアイテムを追加すると、XML の最初のアイテムが上書きされるだけなので、XML ファイルにはアイテムが 1 つしかありません。私はこれを解決します

クラス

public class Visits
{
/*
 * This class represents a single appointment
 */

    private string Customer_Name;
    private string Customer_Address;
    private DateTime Arrival_Time;
    private string Visit_Type;
    private Double Lat1;
    private Double Long1;
    //Private methods. Note the use of DateTime to store arrival time

    public string name{
        //Description property
        set { Customer_Name = value; }
        get {return Customer_Name;}
    }

    public string address
    {//Time property
        set { Customer_Address = value; }
        get { return Customer_Address; }
    }

    public DateTime arrival
    {   //Duration property
        set { Arrival_Time = value; }
        get { return Arrival_Time; }
    }

    public string type
    {
        set { Visit_Type = value; }
        get { return Visit_Type; }
    }

    public Double Lat
    {
        //Description property
        set { Lat1 = value; }
        get { return Lat1; }
    }

    public Double Lon1
    {
        //Description property
        set { Long1 = value; }
        get { return Long1; }
    } 
    public override string ToString()
    {   //Return a String representing the object
        return Visit_Type + "     " + Customer_Name + " " + Customer_Address + " " + Arrival_Time.ToString() + " " + "Latitude  " + Lat1 + " " + "Longitude  " + Long1;
    }
}

}

次にリスト

class List
{
/*
 * This object represents the List. It has a 1:M relationship with the Visit class
 */

    private List<Visits> visits = new List<Visits>();
    //List object use to implement the relationshio with Visits

    public void addVisits(Visits vis)
    {
        //Add a new Visit to the List
        visits.Add(vis);
    }

    public List<String> listVisits()
    {//Generate a list of String objects, each one of which represents a Visit in List.

        List<String> listVisits = new List<string>();
        //This list object will be populated with Strings representing the Visits in the lists

        foreach (Visits vis in visits)
        {
            String visAsString = vis.ToString();
            //Get a string representing the current visit object

            listVisits.Add(visAsString);
            //Add the visit object to the List
        }

        return listVisits;
        //Return the list of strings
    }

    public Visits getVisits(int index)
    {
        //Return the visit object at the <index> place in the list

        int count = 0;
        foreach (Visits vis in visits)
        {
            //Go through all the visit objects
            if (index == count)
                //If we're at the correct point in the list...
                return vis;
            //exit this method and return the current visit
            count++;
            //Keep counting
        }
        return null;
        //Return null if an index was entered that could not be found
    }
}

}

次に、追加するコード

            thePickup.name = txtCustName.Text;
            thePickup.address = txtCustAddress.Text;
            thePickup.arrival = DateTime.Parse(txtArrival.Text);
            thePickup.Dname = txtDeliveryName.Text;
            thePickup.Daddress = txtDaddress.Text;
            thePickup.Lat = Double.Parse(txtLat.Text);
            thePickup.Lon1 = Double.Parse(txtLong.Text);
            thePickup.type = "Pickup";
            //Update thePickup object to reflect any changes made by the user

            XmlSerializer SerializerObj = new XmlSerializer(typeof(Pickups));

        using (TextWriter WriteFileStream = new StreamWriter(@"Pickup.xml", true))
        {
            SerializerObj.Serialize(WriteFileStream, thePickup);
        }

新しいエントリを追加すると、元のエントリの形式が変更されるだけです

4

3 に答える 3

0

XML のアセンブルと作成を処理するには、 XPathでサポートされているライブラリを使用するようにしてください。

C# を使用しているため、「解析」処理にはHtmlAgilityPackをお勧めします。

XML を構築するために、XPathを使用して構築する方法を学習するための優れたソースを次に示します。

C# のネイティブ XMLDocument クラスを使用することもできます。以前に解析ロジックを使用せずにビルドする場合は、より便利な場合があります。

こちらをご覧ください

XPath サンプル:

XML ファイル内の実際のノードのオーバーライドを回避するのに役立つ XPath サンプルを次に示します。

CreateTag("//NODE1/NODE2", "TAG_NAME", tagContent);


    private void CreateTag(string xPath, string tag, string tagContent)
    {
        XmlNode node = _xml.SelectSingleNode(xPath);
        XmlElement element = _xml.CreateElement(tag);

        element.InnerText = tagContent;
        node.AppendChild(element);
    }

セットに同じ名前のノードが複数ある場合:

CreateTag("//SINTEGRA//SEARCH//RECORDS//RECORD[last()]", kv.Key, kv.Value);

last()最後に作成されたノードの後に​​ノードが挿入されるように、lastnode + 1 へのインデックスを返すほとんどの .dlls によって実装される XPath メソッドはどこにありますか?

于 2012-12-05T13:44:46.273 に答える
0

これを試して:

using(TextWriter WriteFileStream = new StreamWriter(@"Pickups.xml", true))
{
    SerializerObj.Serialize(WriteFileStream, thePickup);
}

代わりは。

このboolean trueパラメーターは、StreamWriter がappend既存のファイルを上書きするのではなく、次のブロックを既存のファイルに書き込むことを意味します。

そうしないと、コードによって Pickups.xmlファイルが毎回上書きされます。そして、WriteFileStream オブジェクトを閉じることを忘れないでください。

私はあなたのケースを再現しようとしました:


    public class Pickups
    {
        public string name { get; set; }
        public string address { get; set; }
        public string Dname { get; set; }
        public string Daddress { get; set; }
        public string type { get; set; }
        public DateTime arrival { get; set; }
        public DateTime Lat { get; set; }
        public DateTime Lon1 { get; set; }
    }

class Program
{


    static void Main()
    {
        Pickups thePickup = new Pickups();
        thePickup.name = "nameProp";
        thePickup.address = "addressProp";
        thePickup.arrival = DateTime.Now;
        thePickup.Dname = "txtDeliveryName";
        thePickup.Daddress = "txtDaddress";
        thePickup.Lat = DateTime.Now;
        thePickup.Lon1 = DateTime.Now;
        thePickup.type = "Pickup";
        //Update thePickup object to reflect any changes made by the user

        XmlSerializer SerializerObj = new XmlSerializer(typeof(Pickups));

        using (TextWriter WriteFileStream = new StreamWriter(@"Pickups.xml", true))
        {
            SerializerObj.Serialize(WriteFileStream, thePickup);
        }

        Pickups thePickup1 = new Pickups();
        thePickup1.name = "nameProp2";
        thePickup1.address = "addressProp2";
        thePickup1.arrival = DateTime.Now;
        thePickup1.Dname = "txtDeliveryName2";
        thePickup1.Daddress = "txtDaddress2";
        thePickup1.Lat = DateTime.Now;
        thePickup1.Lon1 = DateTime.Now;
        thePickup1.type = "Pickup2";

        using (TextWriter WriteFileStream = new StreamWriter(@"Pickups.xml", true))
        {
            SerializerObj.Serialize(WriteFileStream, thePickup1);
        }
    }

}

Pickups.xmlファイルでは、期待される結果 (2 つのエンティティ) が得られます

<?xml version="1.0" encoding="utf-8"?>
<Pickups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <name>nameProp</name>
  <address>addressProp</address>
  <Dname>txtDeliveryName</Dname>
  <Daddress>txtDaddress</Daddress>
  <type>Pickup</type>
  <arrival>2012-12-05T15:30:37.809487+01:00</arrival>
  <Lat>2012-12-05T15:30:37.810487+01:00</Lat>
  <Lon1>2012-12-05T15:30:37.810487+01:00</Lon1>
</Pickups><?xml version="1.0" encoding="utf-8"?>
<Pickups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <name>nameProp2</name>
  <address>addressProp2</address>
  <Dname>txtDeliveryName2</Dname>
  <Daddress>txtDaddress2</Daddress>
  <type>Pickup2</type>
  <arrival>2012-12-05T15:30:37.989487+01:00</arrival>
  <Lat>2012-12-05T15:30:37.989487+01:00</Lat>
  <Lon1>2012-12-05T15:30:37.989487+01:00</Lon1>
</Pickups>

プログラムのすべての部分を修正しましたか? コード内の別の場所から同じファイルに書き込むことはありませんか?

于 2012-12-05T13:47:15.820 に答える
0

単一の要素ではなくリストをシリアライズしないでください:

 List<Pickups> list = new List<Pickups>();

 foreach ( var pickup in ... )
    list.Add( pickup );

 ...
 XmlSerializer SerializerObj = new XmlSerializer(typeof(List<Pickups>));

 TextWriter WriteFileStream = new StreamWriter(@"Pickups.xml");
 SerializerObj.Serialize( WriteFileStream, list );
于 2012-12-05T13:54:37.893 に答える