Risipa de key_press | Programare

Programare .Net | Tehnici de programare | Tutoriale | Lectii si exemple

Risipa de key_press | Programare - Programare .Net | Tehnici de programare | Tutoriale | Lectii si exemple

Programare c# | 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.

Category: Uncategorized
  • tequila_cu_varza says:

    Io-s fascinata de programare :D dar doar in stadiul asta :D ca am prins PC prea tarziu, si…Insa daca ar fi sa iau viata de la capat, asta as face, clar!!

    December 11, 2009 at 11:11 pm
  • Alexandra says:

    Foarte util articolul si f usor de inteles..Multumesc:)

    June 10, 2013 at 7:50 pm

Your email address will not be published. Required fields are marked *

*