2011-11-30 16 views
10

voglio salvare i record recuperati dal database in un file XML,
prendere x numero di record da file XML in una raccolta personalizzata List<T>
processo di loro e salvare elementi aggiornati di nuovo in XML file.C# - Salva lista <T> di file XML

'T' è un oggetto semplice con proprietà tipo di valore, qualcosa di simile -

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

Per favore mi guida come posso salvare raccolta personalizzata List<T> di file XML e viceversa?

Inoltre, poiché non sto inviando questo file XML, ha senso utilizzare XmlSerializer come suggerito in alcune delle risposte?

Grazie!

+0

Dipende da 'T' - ha qualche codice di esempio? – BrokenGlass

+0

domanda modificata – iniki

risposta

11

Mentre si potrebbe utilizzare un serializzatore - e molte volte questa è la risposta giusta - io personalmente usare LINQ to XML che ti permettono di essere più flessibile su come il vostro XML dovrebbe assomigliare, cioè creare th e seguente codice XML da una raccolta foos in base alla classe:

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

si potrebbe usare:

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

Utilizzare la classe XmlSerializer. Scorri verso il basso per circa 1/3 degli esempi.

+0

+1 È venuto qui per dire anche la serializzazione. – Jeremy

+0

perché non sto inviando questo file XML, ha senso usare XmlSerializer? – iniki

+1

XMLSerializer consente di convertire un oggetto in XML. Non ha nulla a che fare con "spedire" un file. –

13

Qui ci sono due metodi che usiamo per raggiungere questo obiettivo utilizzando il 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

E l'istanza di T deve avere un costruttore senza parametri. – zionpi

+1

questo non funziona – motto

5

usando il codice seguente (Classe T Tratto da snippet di codice) si sarà in grado di puntate in un file XML con facilità , e senza il fastidio di implimenting 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(); 
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); 
     } 

Passo ChoiceXML di stored procedure quindi SQL Server piace, come di seguito

@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

Puoi salvare il tuo List<T> in un DataTable, quindi 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"); 
+0

Come si riferisce alla domanda? –

+0

cosa intendi? –

+0

La tua [risposta originale] (http://stackoverflow.com/revisions/36350950/1) ha usato un '' persona' di classe che era molto confuso (non riguardava la domanda), specialmente che non hai spiegato quale codice fa in alcun modo.È sempre meglio fornire alcune spiegazioni generali, non solo per incollare il codice. –