2013-03-13 156 views
0

刪除對象我有下面的類序列化,反序列化,追加,獲取,在XML文件C#

[Serializable] 
public class Product 
{ 
    public Product() { } 
    public string ProductID { get; set; } 
    public string Name { get; set; } 
    public string Description { get; set; } 
} 

我想創建對象的XML文件。如果產品ID存在,則更新該節點,否則將該節點添加或附加到xml文件中。

我用下面的代碼序列化對象

public void SerializeNode(object obj, string filepath) 
{ 
    XmlSerializer serializer = new XmlSerializer(obj.GetType()); 
    var writer = new StreamWriter(filepath); 
    serializer.Serialize(writer.BaseStream, obj); 
} 

但都從頭所以如果有新的overwites它在文件中存在的數據創建文件。

所以我在尋找它在xml中添加/追加節點的機制,獲取基於ProductID的節點並刪除節點。

該類可以擴展更多的數據成員,所以代碼應該是動態的,所以我不必在代碼中指定子元素,我只希望它在類級別。

希望有人能幫助

我期待的結構如下

<?xml version="1.0" encoding="utf-8"?> 
<Products> 
    <Product ProductID="1"> 
    <Name>Product Name</Name> 
    <Description>Product Description</Description> 
    </Product> 
    <Product ProductID="2"> 
    <Name>Product Name</Name> 
    <Description>Product Description</Description> 
    </Product> 
    <Product ProductID="3"> 
    <Name>Product Name</Name> 
    <Description>Product Description</Description> 
    </Product> 
</Products> 
+0

使用IRepository模式; http://stackoverflow.com/questions/4528712/what-is-a-irepository-and-what-is-it-used-for – 2013-03-13 10:27:19

回答

0

我不明白的問題:

  1. 反序列化XML到objext
  2. 更改對象
  3. 序列化更新的對象
+0

它不只是一個對象,文件中可以有多個對象 – 2013-03-13 10:21:17

+0

@AdnanZameer,我認爲他指的是根對象..只是將整個文件反序列化爲一個Products對象,進行更改並將其保存迴文件。也許OP可以告訴我們爲什麼這不是採取的方法。 – Matt 2013-03-13 11:01:55

+0

@AdnanZameer:哦,我知道你是OP。哎呀。大聲笑。那麼,也許你可以告訴我們..你爲什麼不反序列化整個對象?你對文件太大或者有什麼問題嗎?如果你給出更多的細節,那麼我們也許可以想出更好的解決方案 – Matt 2013-03-13 11:14:46

0

應該讓你開始一個更好的方向;即手動序列化與XElement

var elmtProducts = new XElement("Products"); 

foreach(var item in ProductsList) 
{ 
    var elmtProduct = new XElement("Product"); 

    elmtProduct.Add(new XElement("Name", "Product Name")); 
    elmtProduct.Add(new XElement("Description", "Product Description")); 

    //if(
    elmtProducts.Add(elmtProduct); 
} 

elmtProducts.Save(new FileStream("blah")); 

現在,你應該能夠解決如何反序列化這個。你也可以把整個東西加載到內存中並用新產品更新,然後重新保存。如果你有這麼多的產品,你不能這樣做,那麼你需要一個數據庫,而不是XML。

0

在這裏,如果你不知道如何反序列化,你可以這樣做:

internal class Program 
    { 
     private static void Main(string[] args) 
     { 
      //var products = new ProductCollection(); 
      //products.Add(new Product { ID = 1, Name = "Product1", Description = "This is product 1" }); 
      //products.Add(new Product { ID = 2, Name = "Product2", Description = "This is product 2" }); 
      //products.Add(new Product { ID = 3, Name = "Product3", Description = "This is product 3" }); 
      //products.Save("C:\\Test.xml"); 

      var products = ProductCollection.Load("C:\\Test.xml"); 

      Console.ReadLine(); 
     } 
    } 

    [XmlRoot("Products")] 
    public class ProductCollection : List<Product> 
    { 
     public static ProductCollection Load(string fileName) 
     { 
      return new FileInfo(fileName).XmlDeserialize<ProductCollection>(); 
     } 

     public void Save(string fileName) 
     { 
      this.XmlSerialize(fileName); 
     } 
    } 

    public class Product 
    { 
     [XmlAttribute("ProductID")] 
     public int ID { get; set; } 

     public string Name { get; set; } 

     public string Description { get; set; } 
    } 

,爲XmlSerialize()XmlDeserialize()你在上面看到,使用我寫了幾年,這些擴展方法回:

public static class XmlExtensions 
{ 
    /// <summary> 
    /// Deserializes the XML data contained by the specified System.String 
    /// </summary> 
    /// <typeparam name="T">The type of System.Object to be deserialized</typeparam> 
    /// <param name="s">The System.String containing XML data</param> 
    /// <returns>The System.Object being deserialized.</returns> 
    public static T XmlDeserialize<T>(this string s) 
    { 
     if (string.IsNullOrEmpty(s)) 
     { 
      return default(T); 
     } 

     var locker = new object(); 
     var stringReader = new StringReader(s); 
     var reader = new XmlTextReader(stringReader); 
     try 
     { 
      var xmlSerializer = new XmlSerializer(typeof(T)); 
      lock (locker) 
      { 
       var item = (T)xmlSerializer.Deserialize(reader); 
       reader.Close(); 
       return item; 
      } 
     } 
     catch 
     { 
      return default(T); 
     } 
     finally 
     { 
      reader.Close(); 
     } 
    } 

    /// <summary> 
    /// Deserializes the XML data contained in the specified file. 
    /// </summary> 
    /// <typeparam name="T">The type of System.Object to be deserialized.</typeparam> 
    /// <param name="fileInfo">This System.IO.FileInfo instance.</param> 
    /// <returns>The System.Object being deserialized.</returns> 
    public static T XmlDeserialize<T>(this FileInfo fileInfo) 
    { 
     string xml = string.Empty; 
     using (FileStream fs = new FileStream(fileInfo.FullName, FileMode.Open, FileAccess.Read)) 
     { 
      using (StreamReader sr = new StreamReader(fs)) 
      { 
       return sr.ReadToEnd().XmlDeserialize<T>(); 
      } 
     } 
    } 

    /// <summary> 
    /// <para>Serializes the specified System.Object and writes the XML document</para> 
    /// <para>to the specified file.</para> 
    /// </summary> 
    /// <typeparam name="T">This item's type</typeparam> 
    /// <param name="item">This item</param> 
    /// <param name="fileName">The file to which you want to write.</param> 
    /// <returns>true if successful, otherwise false.</returns> 
    public static bool XmlSerialize<T>(this T item, string fileName) 
    { 
     return item.XmlSerialize(fileName, true); 
    } 

    /// <summary> 
    /// <para>Serializes the specified System.Object and writes the XML document</para> 
    /// <para>to the specified file.</para> 
    /// </summary> 
    /// <typeparam name="T">This item's type</typeparam> 
    /// <param name="item">This item</param> 
    /// <param name="fileName">The file to which you want to write.</param> 
    /// <param name="removeNamespaces"> 
    ///  <para>Specify whether to remove xml namespaces.</para>para> 
    ///  <para>If your object has any XmlInclude attributes, then set this to false</para> 
    /// </param> 
    /// <returns>true if successful, otherwise false.</returns> 
    public static bool XmlSerialize<T>(this T item, string fileName, bool removeNamespaces) 
    { 
     object locker = new object(); 

     XmlSerializerNamespaces xmlns = new XmlSerializerNamespaces(); 
     xmlns.Add(string.Empty, string.Empty); 

     XmlSerializer xmlSerializer = new XmlSerializer(typeof(T)); 

     XmlWriterSettings settings = new XmlWriterSettings(); 
     settings.Indent = true; 
     settings.OmitXmlDeclaration = true; 

     lock (locker) 
     { 
      using (XmlWriter writer = XmlWriter.Create(fileName, settings)) 
      { 
       if (removeNamespaces) 
       { 
        xmlSerializer.Serialize(writer, item, xmlns); 
       } 
       else { xmlSerializer.Serialize(writer, item); } 

       writer.Close(); 
      } 
     } 

     return true; 
    } 
} 

我希望這是有用的。如果沒有,請根據您的要求提供更多有關您的情況的信息。