Sunteți pe pagina 1din 4

http://blog.zeltera.eu/?

p=310

Crearea unui document XML


Salvarea unor date (serializare), pastrarea preferintelor user-ului, salvarea unui pas intermediar sau a
progresului unui proces in program, pastrarea in memorie (sa zicem intr-o aplicatie web, in Session) a unor
date, trimiterea de informatii intre doua aplicatii (o aplicatie de tip chat) sau alte situatii la care nu ma
gandesc acum pot fi “rezolvate” prin intermediul unui document XML.
Sa presupunem ca avem o aplicatie, si trebuie sa salvam preferintele userului: pozitia ferestrei, tipul de font,
imaginea de fundal aleasa etc. Una dintre caile cele mai simple de a face asta e sa creezi un document XML
pe care sa il salvezi undeva pe diskul calculatorului unde ruleaza aplicatia.

Pentru a face asta avem nevoie ca in timpul executiei aplicatiei sa creem, programatic, un document XML.
Daca ieri am descris cum sa citim un astfel de document, astazi arata cum se poate crea unul. Nu prea am la
acest nivel aplicatii prea bune pentru exemple, asa ca o sa incerc cu un exemplu banal, in sensul de clasic in
exercitii, si anume o lista de studenti. Asadar, se da o lista de studenti. Trebuie creat un document XML care
sa salveze lista respectiva intr-o forma de genul:
<studenti>
<student>Nume_student</student>
<!-- etc, more data -->
</studenti>
Programul care face aceasta operatie simpla arata asa:
/*
* Create a Xml document "on the fly"
*/

using System;
using System.Collections.Generic;
using System.Xml;

namespace zeltera.xmlTutorials
{
class Program
{
const string XML_FILE_PATH = "c:\\test.xml";

static void Main(string[] args)


{
string[] students = new string[] { "Ion", "Ioana", "Gelu", "Ana", "Vasile" };
XmlDocument xml = new XmlDocument();
XmlDeclaration xml_declaration = xml.CreateXmlDeclaration("1.0", "utf-8", ""); //create an
xmlDeclaration
XmlNode root = xml.CreateNode(XmlNodeType.Element, "students", ""); //create a root node

foreach (string student in students)


{ //foreach student in collection create a xml node
XmlNode tmpNode = xml.CreateNode(XmlNodeType.Element, "student", "");
tmpNode.InnerText = student;
root.AppendChild(tmpNode); //add the node as child of the root node
}

xml.AppendChild(xml_declaration);
xml.AppendChild(root);
xml.Save(XML_FILE_PATH);
}
}
}
Vreau sa fac mici precizari: se creaza un obiect de tipul XmlDocument care va juca rol de schelet pentru
constructia documentului final (cel care ne intereseaza). Pe acest schelet se creaza (si adaoga) elementele
componente, respectiv XmlDeclaration, element obligatoriu in orice xml, si un element root, care in cazul
acesta este students (plural), element caruia ii vor fi adaugate elemente de tip student (singular), care
element, deocamdata, va contine numai numele studentului.
Elementele unui document Xml se creaza de catre obiectul XmlDocument (nu au constructor public), si pot
fi adaugate doar la documentul care le-a creat. In cazul acesta, singurul tip de element creat e XmlNode, care
reprezinta, asa cum numele sugereaza, un nod in structura arborescenta a documentului.
La rulare, programul de mai sus genereaza fisierul xml cu urmatorul continut:
<?xml version="1.0" encoding="utf-8"?>
<students>
<student>Ion</student>
<student>Ioana</student>
<student>Gelu</student>
<student>Ana</student>
<student>Vasile</student>
</students>
Asta a fost un prim exemplu. Nu imi pot imagina acum un exemplu mai simplu. In continuare as vrea sa
complic un pic lucrurile, prin adaugarea la numele studentului si varsta, anul de studii si specialitatea. Acum
un nod care descrie un student va arata asa:
<student an="1" varsta="21">
<nume>Ion</nume>
<specialitatea>chimie</specialitatea>
</student>
si as vrea sa precizez introducerea varstei si a anului de studii ca atribute ale elementului student.
programul care genereaza acest Xml este urmatorul (de obicei datele vin dintr-o baza de date, dintr-un
formular etc, insa in exemplu datele despre student vor fi date de forma: “Ion, 1, 22, chimie”):
/*
* Create a Xml document "on the fly"
*/

using System;
using System.Collections.Generic;
using System.Xml;

namespace zeltera.xmlTutorials
{
class Program
{
const string XML_FILE_PATH = "c:\\test.xml";

static void Main(string[] args)


{
string[] students = new string[] { "Ion, 1, 22, chimie", "Ioana, 1, 23, fizica", "Gelu, 2, istorie, 23",
"Ana, 4, 23, istorie", "Vasile, 2, 22, chimie" };

XmlDocument xml = new XmlDocument();


XmlDeclaration xml_declaration = xml.CreateXmlDeclaration("1.0", "utf-8", ""); //create an
xmlDeclaration
XmlNode root = xml.CreateNode(XmlNodeType.Element, "students", ""); //create a root node

foreach (string student in students)


{ //foreach student in collection create a xml node
string[] stInfo = student.Split(',');
XmlNode studentNode = xml.CreateNode(XmlNodeType.Element, "student", "");
XmlAttribute y = xml.CreateAttribute("an");
y.Value = stInfo[1].Trim();
XmlAttribute age = xml.CreateAttribute("varsta");
age.Value = stInfo[2].Trim();
studentNode.Attributes.Append(y); //add the attribute
studentNode.Attributes.Append(age);

//voi adauga urmatoarele 2 noduri... direct:


XmlNode studentName = xml.CreateNode(XmlNodeType.Element, "nume", "");
studentName.InnerText = stInfo[0].Trim();
XmlNode studentSpec = xml.CreateNode(XmlNodeType.Element, "specialitatea", "");
studentSpec.InnerText = stInfo[3].Trim();
studentNode.AppendChild(studentName);
studentNode.AppendChild(studentSpec);

root.AppendChild(studentNode); //add the node as child of the root node


}

xml.AppendChild(xml_declaration);
xml.AppendChild(root);
xml.Save(XML_FILE_PATH);
}
}
}
care program, la rulare, genereaza urmatorul document Xml:
<?xml version="1.0" encoding="utf-8"?>
<students>
<student an="1" varsta="22">
<nume>Ion</nume>
<specialitatea>chimie</specialitatea>
</student>
<student an="1" varsta="23">
<nume>Ioana</nume>
<specialitatea>fizica</specialitatea>
</student>
<student an="2" varsta="istorie">
<nume>Gelu</nume>
<specialitatea>23</specialitatea>
</student>
<student an="4" varsta="23">
<nume>Ana</nume>
<specialitatea>istorie</specialitatea>
</student>
<student an="2" varsta="22">
<nume>Vasile</nume>
<specialitatea>chimie</specialitatea>
</student>
</students>
.
De remarcat noul element XmlAttribute creat tot din obiectul XmlDocument.
Solutia propusa de mine nu este deloc eleganta, o varianta eleganta ar putea deveni prin adaugarea unor
netode “helper” care sa primeasca argumente datele de intrare si care sa genereze nodurile care trebuiesc
adaugate. Nu o sa rescriu tot exemplul, ci o sa arat cam cum ar trebui creata o astfel de metoda:
public XmlNode CreateStudentNode(XmlDocument doc, string name, string age, string spec, string
year)
{
XmlNode studentNode = doc.CreateNode(XmlNodeType.Element, "student", "");
XmlAttribute y = doc.CreateAttribute("an");
y.Value = year;
XmlAttribute ageAtr = doc.CreateAttribute("varsta");
ageAtr.Value = age;
studentNode.Attributes.Append(y);
studentNode.Attributes.Append(ageAtr);

XmlNode studentName = doc.CreateNode(XmlNodeType.Element, "nume", "");


studentName.InnerText = name;
XmlNode studentSpec = doc.CreateNode(XmlNodeType.Element, "specialitatea", "");
studentSpec.InnerText = spec;
studentNode.AppendChild(studentName);
studentNode.AppendChild(studentSpec);

return studentNode;
}
iar aceasta functie “infrumuseteaza” un pic codul, prin faptul ca este impartita in diviziuni crearea
documentului, ceea ce usureaza citirea si intelegerea codului (si, bineinteles, debug-ul).
Cam asta pentru acum. Multumesc celor care citesc acete articole ai as aprecia comntarii, pareri, semnalare
de greseli, sugestii, exemple mai bune decat cele prezentatea de mine etc.

S-ar putea să vă placă și