我有以下课程
[Serializable]
public class Product
{
public Product() { }
public string ProductID { get; set; }
public string Name { get; set; }
public string Description { get; set; }
}
我想从object创建一个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>
答案 0 :(得分:0)
我没有遇到问题:
答案 1 :(得分: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。
答案 2 :(得分: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;
}
}
我希望这很有用。如果没有,请按照要求向我们提供有关您情况的更多信息。