Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/321.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# XML文件C中的序列化、反序列化、追加、获取、删除对象#_C#_Xml_Xml Serialization - Fatal编程技术网

C# XML文件C中的序列化、反序列化、追加、获取、删除对象#

C# XML文件C中的序列化、反序列化、追加、获取、删除对象#,c#,xml,xml-serialization,C#,Xml,Xml Serialization,我有以下课程 [Serializable] public class Product { public Product() { } public string ProductID { get; set; } public string Name { get; set; } public string Description { get; set; } } 我想从对象创建一个XML文件。如果产品id存在,请以其他方式更新该节点,并在xml文件中添加或追加该节点 我

我有以下课程

[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);
}
但它每次都会从头开始创建文件,因此如果文件中存在数据,它会使用新的数据对其进行重载

所以我在寻找一种机制,它在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>

品名
产品说明
品名
产品说明
品名
产品说明

我不明白这个问题:

  • 将xml反序列化为对象文本
  • 对对象进行更改
  • 序列化更新的对象

  • 应该让你从一个更好的方向开始;即使用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

    在这里,如果您不确定如何反序列化,可以执行以下操作:

    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; }
        }
    

    我希望这是有用的。如果没有,请按要求向我们提供有关您的情况的更多信息。

    这不仅仅是一个对象,在同一个对象中可以有多个对象file@AdnanZameer,我想他指的是根对象。。只需将整个文件反序列化为一个Products对象,进行更改并将其保存回文件。也许OP可以告诉我们为什么这不是所采取的方法。@AdnanZameer:哦,我知道你是OP。噢。哈哈。那么,也许你可以告诉我们。。为什么不反序列化整个对象?你对文件太大有什么问题吗?如果你能提供更多的细节,我们也许能想出更好的办法solutions@AdnanZameer是对象的数组/列表吗?我也得不到:创建一个容器对象,其属性是对象列表使用IRepository模式;
    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;
        }
    }