17

I want to save records fetched from database in an XML file,
take x number of records from XML file into a custom collection List<T>
process them and save updated items back into XML file.

'T' is a simple object with value type properties, something like -

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

Please guide me how can I save custom collection List<T> to XML file and vice-versa?

Also, because I am not sending out this XML file, will it make sense to go for XmlSerializer as suggested in some of the replies?

Uwe Keim
  • 39,551
  • 56
  • 175
  • 291
inutan
  • 10,558
  • 27
  • 84
  • 126

6 Answers6

18

Here are two methods that we use to accomplish this using the 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();
    }
 }
Aaron
  • 321
  • 1
  • 7
16

While you could use a serializer - and many times this is the right answer - I personally would use Linq to XML which would allow you to be more flexible on how your XML should look like, i.e. to create the following XML from a collection foos based on your class:

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

You could use:

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))));
BrokenGlass
  • 158,293
  • 28
  • 286
  • 335
14

Using the code below (Class T Taken from your code snippet) you will be able to serialize into an XML file with ease, and without the hassle of implementing 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();
DGaleano
  • 137
  • 9
Yantrio
  • 141
  • 2
2

Use the XmlSerializer class. Scroll down about 1/3 of the way for the examples.

  • because I am not sending out this XML file, will it make sense to go for XmlSerializer? – inutan Nov 30 '11 at 23:44
  • 1
    XMLSerializer allows you to convert an object to XML. It has nothing to do with "sending out" a file. – K Mehta Nov 30 '11 at 23:46
  • @iniki, the original question stated you wanted to save the objects to an XML file. It said nothing about sending anything anywhere. Quote: "save updated items back into XML file." The updated question *still* says you're wanting to save the objects to XML. –  Dec 01 '11 at 01:09
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);
        }

Pass ChoiceXML to Stored procedure then SQL Server Do like as below

@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
Kumar Saurabh
  • 2,297
  • 5
  • 29
  • 43
-1

You Can save Your List<T> into a DataTable then 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");
Ali Besharati
  • 918
  • 12
  • 25
  • How does that relate to the question? – Adam Michalik Apr 01 '16 at 08:14
  • Your [original response](http://stackoverflow.com/revisions/36350950/1) used a class `person` which was very confusing (did not relate to the question), especially that you didn't explain what the code does in any way. It's always best to provide some general explanation, not just to paste the code. – Adam Michalik Apr 01 '16 at 13:49
  • Ok Got it, Thank you my friend – Ali Besharati Apr 01 '16 at 13:58