如何使用转发器项目有效地更新 XML 文件
本文关键字:更新 XML 文件 有效地 项目有 何使用 转发器 项目 | 更新日期: 2023-09-27 17:56:38
我正在将XML文件绑定到中继器,每个项目都在文本框中。触发"保存"操作时,我需要将更改写回 XML 文件。我的问题是最有效的方法是什么,请记住XML文件非常小。
我能想到三个,我不知道哪个最好:
- 循环转发器,在 XML 文件中查找匹配的 ID,更新这些节点
- 循环 XML 文件,在转发器中找到匹配的 ID,更新这些节点
- 编写新的 XML 文件(替换旧文件)
谢谢!
使用我的 XML 文件的外观示例进行了更新:
<?xml version="1.0" encoding="UTF-8"?>
<Link>
<LinkNode>
<Section>New York</Section>
<Header>New York</Header>
<Item>IT/ Phone Support</Item>
<Details>Ext 5.8115</Details>
<ID>0</ID>
<HyperLink>0</HyperLink>
</LinkNode>
<LinkNode>
<Section>New York</Section>
<Header />
<Item>Email</Item>
<Details>info@gld.com</Details>
<ID>1</ID>
<HyperLink>2</HyperLink>
</LinkNode>
</Link>
这是我的班级:
public class Link
{
public String Section { get; set; }
public String Header { get; set; }
public String Item { get; set; }
public String Details { get; set; }
public Int32 ID { get; set; }
public Int32 Hyperlink { get; set; }
}
我的链接构造函数:
var LinksList = new List<Links>();
var query = links_xml.Root.Descendants("LinkNode").Select(d => d);
foreach (var q in query)
{
var linklist = new Links((!string.IsNullOrEmpty(q.Element("Header").Value)) ? q.Element("Header").Value : "",
(!string.IsNullOrEmpty(q.Element("Item").Value)) ? q.Element("Item").Value : "",
(!string.IsNullOrEmpty(q.Element("Details").Value)) ? q.Element("Details").Value : "",
(int)q.Element("ID"), (int)q.Element("HyperLink"));
LinksList.Add(linklist);
}
还可以创建包含所需属性的类对象。将 XML 的读取和写入放在 DAL 层中。这样,DAL 就会传递并接收这些对象的List<Url>
,并从应用程序的其余部分抽象出数据访问(在本例中为 XML)。
如果选择更改数据存储方法(更改为 SQL 等),则只需更改 DAL 方法,其余代码不受影响。
如果您需要一些代码来说明,请告诉我。
编辑:(一些代码)
假设您的元素具有以下属性,这将是您的类:
public class Url
{
public int Id {get; set;}
public string DisplayName {get; set;}
public string Url {get; set;}
}
然后,DAL 类将如下所示:
/// <summary>
/// Handles data access for Url entities
/// </summary>
public static class UrlDAL
{
/// <summary>
/// The path where the file resides
/// </summary>
const string __FilePath = @"~'App_Data'";
/// <summary>
/// The name of the file
/// </summary>
const string __FileName = "UrlList.xml";
/// <summary>
/// The name of the temporary file. Used to keep a copy of the file if saving the new file fails.
/// </summary>
const string __FileNameTemp = "UrlList_TEMP.xml";
/// <summary>
/// Retrieves a list of url entity objects
/// </summary>
/// <returns></returns>
internal static List<Url> Retrieve()
{
List<Url> urls = null;
try
{
//read xml file
XDocument data = XDocument.Load(HttpContext.Current.Server.MapPath(Path.Combine(UrlDAL.__FilePath, UrlDAL..__FileName)));
//convert to list
urls = Xml.DeserializeCollection<Url>(data);
}
catch (Exception e)
{
//perform logging / error handling
}
return urls;
}
/// <summary>
/// Saves the list of Url entities
/// </summary>
/// <param name="urls">The list of url objects to save</param>
internal static void Create(List<Url> urls)
{
try
{
//convert list into xml document
XDocument file = Xml.SerializeCollection<Url>(urls);
//rename the old file so you have a copy of it if saving the new file fails
File.Copy(Path.Combine(UrlDAL.__FilePath, UrlDAL.__FileName), Path.Combine(UrlDAL.__FilePath, UrlDAL.__FileNameTemp));
//saving the new file will overwrite the existing file
file.Save(UrlDAL.__FilePath);
//delete the old file
File.Delete(Path.Combine(UrlDAL.__FilePath, UrlDAL.__FileNameTemp));
}
catch (Exception e)
{
//perform logging / error handling
//you should also alert yourself of this error so you can manually restore the old file
}
}
}
以下是用于 XML 序列化/反序列化的扩展方法:
public static class Xml
{
/// <summary>
/// Converts an XDoc into a List<T> of entities
/// </summary>
/// <typeparam name="T">Any serializable object</typeparam>
/// <param name="doc"></param>
/// <returns></returns>
public static List<T> DeserializeCollection<T>(XDocument doc)
{
if (doc == null)
return null;
try
{
XmlSerializer serializer = new XmlSerializer(typeof(List<T>));
XmlReader reader = doc.CreateReader();
List<T> result = (List<T>)serializer.Deserialize(reader);
reader.Close();
return result;
}
catch (Exception e)
{
//perform logging / error handling
return null;
}
}
/// <summary>
/// Converts a List<T> of entities into an XDoc.
/// </summary>
/// <typeparam name="T">Any serializable object</typeparam>
/// <param name="paramList"></param>
public static XDocument SerializeCollection<T>(List<T> paramList)
{
if (paramList == null)
return null;
XDocument doc = new XDocument();
try
{
XmlSerializer serializer = new XmlSerializer(paramList.GetType());
XmlWriter writer = doc.CreateWriter();
serializer.Serialize(writer, paramList);
writer.Close();
return doc;
}
catch (Exception e)
{
//perform logging / error handling
return null;
}
}
}
不要忘记添加对以下命名空间的引用:
using System.IO;
using System.Xml;
using System.Xml.Linq;
using System.Xml.Serialization;
话虽如此,你会这样称呼 DAL:
//to retrieve the list of urls
List<Url> urls = UrlDAL.Retrieve();
//to save the new list of urls to an xml file
List<Url> urls = [BUILD URL ENTITIES FROM REPEATER];
UrlDAL.Create(urls)
编辑:创建 XML 的提示
为了避免反序列化 XML 时出现任何问题(XML 对它将解析的内容可能非常挑剔),我倾向于在代码中创建一些(或全部)我想使用的类,并通过 Xml.Serialize 方法运行 List。然后,我使用在那里创建的 xml 作为创建 XML 文件的起点。
编辑 从转发器创建实例
循环遍历转发器中的每个项时,可以使用 .NET 的对象初始值设定项,如下所示:
List<Links> links = new List<Links>();
foreach (RepeaterItem item in rptLinks.Items)
{
//find all your controls and their values
string details = ((TextBox)e.Item.Findcontrol("txtDetails")).Text;
//do this for each control
//use object initialization here
links.Add(new Link {Details = details, [PROPERTY NAME] = [REPEATER ITEM VALUE], etc});
}
有关此功能的良好说明,请参阅MSDN:对象和集合初始值设定项(C# 编程指南)
呵呵
使用 XmlDocument 加载 xml,然后浏览它以查找包含要更改的值的元素。
System.Xml.XmlDocument xmlDocument = new System.Xml.XmlDocument();
xmlDocument.Load(<filename or stream>);
Now, choose the most suitable method for you to find the elements or
attributes you want to change:
// For example:
XmlNodeList elemList = xmlDocument .GetElementsByTagName("Machine");
for (int i=0; i < elemList.Count; i++)
{
elemList[i].InnerXml = "Whateveryouwant";
}
然后,调用 Save 方法以保存更改。
xmlDocument.Save(...);