将 List<T> 保存到 XML 文件

17

我希望将从数据库中获取的记录保存在XML文件中,
从XML文件中取出x条记录到自定义集合List<T>中,
处理它们并将更新后的项保存回XML文件中。

'T'是一个具有值类型属性的简单对象,类似于 -

public class T
{
   public int Id {get; set;}
   public string property1 {get; set;}
   public string property2 {get; set;}
}

请指导我如何将自定义集合List<T>保存为XML文件,反之亦然?
此外,因为我不会发送此XML文件,所以是否有必要像一些回复中建议的那样使用XmlSerializer?

这取决于 T - 有一些示例代码吗? - BrokenGlass
6个回答

18
这里有两种使用XMLSerializer实现此目的的方法:
 public static T FromXML<T>(string xml)
 {
     using (StringReader stringReader = new StringReader(xml))
     {
        XmlSerializer serializer = new XmlSerializer(typeof(T));
        return (T)serializer.Deserialize(stringReader);
     }
 }

 public string ToXML<T>(T obj)
 {
    using (StringWriter stringWriter = new StringWriter(new StringBuilder()))
    {
        XmlSerializer xmlSerializer = new XmlSerializer(typeof(T));
        xmlSerializer.Serialize(stringWriter, obj);
        return stringWriter.ToString();
    }
 }

2
T的实例必须具有无参构造函数。 - zionpi

16

虽然你可以使用序列化器(serializer)- 在许多情况下这是正确的答案 - 但我个人会使用Linq to XML,它可以让你在XML的外观上更加灵活,即从一个集合foos基于你的类来创建以下XML:

<Foos>
  <foo Id="1" property1="someprop1" property2="someprop2" />
  <foo Id="1" property1="another" property2="third" />
</Foos>

你可以使用:

var xml = new XElement("Foos", foos.Select( x=> new XElement("foo", 
                                                new XAttribute("Id", x.Id), 
                                                new XAttribute("property1", x.property1), 
                                                new XAttribute("property2", x.property2))));

14

使用以下代码(从您的代码片段中获取的T类),您将能够轻松地将对象序列化为XML文件,而无需实现ISerializable接口

[Serializable()]
public class T
{
    public int Id {get; set;}
    public string property1 {get; set;}
    public string property2 {get; set;}
}

...

List<T> data = new List<T>()

... // populate the list

//create the serialiser to create the xml
XmlSerializer serialiser = new XmlSerializer(typeof(List<T>));

// Create the TextWriter for the serialiser to use
TextWriter filestream = new StreamWriter(@"C:\output.xml");

//write to the file
serialiser.Serialize(filestream , data);

// Close the file
filestream.Close();

2
使用 XmlSerializer 类。向下滚动大约三分之一以获取示例。

因为我不会发送此XML文件,使用XmlSerializer有意义吗? - inutan
1
XMLSerializer允许您将对象转换为XML。它与“发送”文件无关。 - K Mehta
@iniki,原问题中提到您想要将对象保存到XML文件中。它没有提到任何关于发送任何东西的内容。引用:“将更新后的项目保存回XML文件。”更新后的问题仍然表示您想要将对象保存到XML中。 - user47589

0
List<BI_QA_ChoiceEntity> choiceSet = new List<BI_QA_ChoiceEntity>();
        choiceSet = biEntityObj.ChoiceSet;

        XmlDocument ChoiceXML = new XmlDocument();
        ChoiceXML.AppendChild(ChoiceXML.CreateElement("CHOICESET"));
        foreach (var item in choiceSet)
        {
            XmlElement element = ChoiceXML.CreateElement("CHOICE");
           // element.AppendChild(ChoiceXML.CreateElement("CHOICE_ID")).InnerText = Convert.ToString(item.ChoiceID);
            element.AppendChild(ChoiceXML.CreateElement("CHOICE_TEXT")).InnerText = Convert.ToString(item.ChoiceText);
            element.AppendChild(ChoiceXML.CreateElement("SEQUENCE")).InnerText = Convert.ToString(item.Sequence);
            element.AppendChild(ChoiceXML.CreateElement("ISCORRECT")).InnerText = Convert.ToString(item.IsCorrect);
            ChoiceXML.DocumentElement.AppendChild(element);
        }

将ChoiceXML传递给存储过程,然后在SQL Server中执行以下操作:
@Choice_XML VARCHAR(MAX)=NULL

 IF(@Choice_XML<>'')  
                BEGIN  
                    SET @intDocHandle =0
                    --Create an internal representation of the XML document.  
                    EXEC sp_xml_preparedocument @intDocHandle OUTPUT, 

@Choice_XML  

                --SET @ChoiceID = (SELECT  max([choice_id])+1 AS 'ChoiceID'  from BI_QUESTION_CHOICE)

                --Insert 
                INSERT BI_QUESTION_CHOICE
                (
                    [choice_id],
                    [choice_descr],
                    [sequence],
                    [question_id],
                    [is_correct],
                    [created_by],
                    [created_dt],
                    [modified_by],
                    [modified_dt]
                )
                SELECT (SELECT  max([choice_id])+1 AS 'ChoiceID'  from BI_QUESTION_CHOICE),  
                    CASE WHEN CHOICE_TEXT='' THEN NULL ELSE CHOICE_TEXT END, 
                    CASE WHEN SEQUENCE='' THEN NULL ELSE SEQUENCE END,
                    QuestionID, 
                    CASE WHEN ISCORRECT='' THEN NULL ELSE ISCORRECT END,
                    'mbathini',  
                     GETDATE(),  
                    'mbathini', 
                    GETDATE()  
                FROM OPENXML(@intDocHandle,'/CHOICESET/CHOICE', 3)  
                WITH  
                (CHOICE_TEXT VARCHAR(500), 
                 SEQUENCE VARCHAR(50),
                 QuestionID INT,
                 ISCORRECT bit)

END

-1

你可以将你的 List<T> 保存到 DataTable 中,然后使用 WriteXml 方法写入。

    T t0 = new T();
       t0.id=1;
       t0.property1="John";
       t0.property2="Doe";
    List<T> Tlist = new List<T>();
       Tlist.Add(t0);

    DataTable dt = new DataTable();
       dt.TableName = "People";
       dt.Columns.Add("ID");
       dt.Columns.Add("Name");
       dt.Columns.Add("Lastname");


        foreach(var item in tlist)
        {
            dt.Rows.Add();
            dt.Rows[dt.Rows.Count-1]["ID"] = item.name;
            dt.Rows[dt.Rows.Count - 1]["Name"] = item.id_cod;
            dt.Rows[dt.Rows.Count - 1]["Lastname"] = item.id_cod;


        }
        dt.WriteXml("test.Xml");

这与问题有什么关系? - Adam Michalik
你的原始回答使用了一个名为person的类,这非常令人困惑(与问题无关),特别是你没有以任何方式解释代码的作用。最好提供一些通用的解释,而不仅仅是粘贴代码。 - Adam Michalik
好的,明白了,谢谢你,我的朋友。 - Ali Besharati

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接