Сохранить список <T> в файл XML
Я хочу сохранить записи, извлеченные из базы данных в файле XML,
взять x количество записей из файла XML в пользовательский List<T>
коллекции 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, как предлагается в некоторых ответах?
Ответы
Ответ 1
Хотя вы можете использовать сериализатор - и много раз это правильный ответ, я лично использовал Linq для XML, который позволит вам быть более гибкими в отношении того, как должен выглядеть ваш XML, т.е. создать следующий XML из коллекция foos
на основе вашего класса:
<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))));
Ответ 2
Вот два метода, которые мы используем для выполнения этого с помощью 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();
}
}
Ответ 3
Используя приведенный ниже код (класс 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();
Ответ 4
Используйте класс XmlSerializer. Прокрутите вниз примерно на 1/3 пути для примеров.
Ответ 5
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);
}
Pass 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
Ответ 6
Вы можете сохранить свой 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");