Linq XML Datagrid Änderungen in XML speichern

Answered Linq XML Datagrid Änderungen in XML speichern

  • Samstag, 14. April 2012 09:41
     
      Enthält Code

    Hi ich habe eine XML Datei die in ein Datagrid eingelesen wird.
    Mein Code:

     private void radButton2_Click(object sender, EventArgs e)
            {
                XDocument doc = XDocument.Load(radTextBox1.Text);
                //all current flash ads in the feed
                var result = from item in doc.Descendants("flash")
                             select new flash
                             {
                                 geID = item.Attribute("geId").Value,
                                 deleted = item.Attribute("geDelete").Value,
                                 Name = item.Element("generalSettings").Element("title").Value,
                                 URL = item.Element("generalSettings").Element("productUrl").Value,
                                 Category = item.Element("generalSettings").Element("categories").Element("category").Element("categoryId").Value,
                                 Keywords = string.Join(",", (from keyword in item.Element("generalSettings").Element("keywords").Elements("keyword")
                                                              select (string)keyword).ToArray()),
                                 paCategories = item.Element("generalSettings").Element("paCategories").Value,
                                 AdGroupID = item.Element("generalSettings").Element("adGroupId").Value,
                                 flashDynamic = item.Element("flashDynamic").Value,
                                 flashUrl = item.Element("flashUrl").Value,
                                 width = item.Element("flashWidth").Value,
                                 height = item.Element("flashHeight").Value,
                                 FlashVersion = item.Element("flashVersion").Value,
                                 flashWindowMode = item.Element("flashWindowMode").Value,
                                 SupportsIframe = item.Element("flashSupportsIframe").Value,
                                 SupportsJavascript = item.Element("flashSupportsJavascript").Value,
                                 SupportsPopunder = item.Element("flashSupportsPopunder").Value,
                                 SupportsPopup = item.Element("flashSupportsPopup").Value
                             }; 
    
     BindingSource bs = new BindingSource();
                bs.DataSource = result.ToList();
                radGridViewFlash.DataSource = bs;

    Hierzu gibt es noch eine einfache Klasse flash, die wie folgt aussieht:

    public class flash
        {
            public string geID { get; set; }
            public string deleted { get; set; }
            public string Name { get; set; }
            public string URL { get; set; }
            public string Category { get; set; }
            public string Keywords { get; set; }
            public string paCategories { get; set; }
            public string AdGroupID { get; set; }
            public string flashDynamic { get; set; }
            public string flashUrl { get; set; }
            public string FlashVersion { get; set; }
            public string width { get; set; }
            public string height { get; set; }
            public string flashVersion { get; set; }
            public string flashWindowMode { get; set; }
            public string SupportsIframe { get; set; }
            public string SupportsJavascript { get; set; }
            public string SupportsPopunder { get; set; }
            public string SupportsPopup { get; set; }
    
    
    
    
        }

    Ich lade die Daten der XML Datei nun in das DataGridView. Dieses ist editierbar jedoch werden die Änderungen logischerweise nicht in der XML Datei übernommen. Könnte mir bitte einer helfen Änderungen im DataGrid über einen "Save" Button in die XML zu schreiben?

    Das Gridview nach dem Upload:


    Danke und Gruß
    Tom

Alle Antworten

  • Sonntag, 15. April 2012 18:29
    Moderator
     
     Beantwortet Enthält Code

    Hallo Tom,

    Mir ist nicht ganz klar, warum Du dein Telerik-Grid nicht über Serialisierung/Deserialisierung befüllst. Normalerweise würde man zunächst über das XSD-Tool eine serialisierbare Klasse (ausgehend von der XML-Datei) erzeugen. Instanzen dieser Klasse würde man dann am besten in eine typisierte Liste einfügen und diese über XmlSerializer serialisieren/deserializierenin der Telerik-Dokumentation findest Du sicherlich Beispiele dazu).

    Ein anderer Weg - wenn im konkreten Szenario möglich - würde darin bestehen, DataSet.ReadXml() oder DataTable.ReadXml() zu verwenden. Da ich die ursprüngliche Datenstruktur nicht kenne, kann ich verständlicherweise nicht sagen, ob das für dich machbar ist. Ist aber eine Überlegung wert.

    Nun zum "manuellen Serialisieren". Da bleibt dir nichts anderes übrig, als die List<T> an die Du bindest sequentiell abzuarbeiten und evtl. Änderungen am XDocument entspr. vorzunehmen (oder gleich ein neues XDocument mit der gleichen Struktur aber mit den neuen Daten zu erzeugen).

    Das könnte in etwa so aussehen (skizziert):

    private void buttonSave_Click(object sender, EventArgs e)
    {
        List<flash> boundFlashDataList = bs.DataSource as List<flash>;
        if (boundFlashDataList != null)
        {
            // Gelöschte flash-Elemente im XML-Quelldocument 
            // als gelöscht markieren
            var currentIDs = (from li in boundFlashDataList
                              select li.geID).ToList();
            var deletedItems = (from item in doc.Descendants("flash")
                               where !currentIDs.Contains(item.Attribute("geId").Value)
                               select item).ToList();
            deletedItems.ForEach(deletedItem => {
                deletedItem.Attribute("geDelete").Value = "yes";
            });
            // Geänderte Daten
            boundFlashDataList.ForEach(candidateFlashItem => {
                var flashElements = doc.Descendants("flash");
                if (flashElements != null)
                {
                    var flashItemWithSameID = flashElements.Where(currentElement => currentElement.Attribute("geId").Value == candidateFlashItem.geID).FirstOrDefault();
                    if (flashItemWithSameID != null)
                    {
                        var generalSettings = flashItemWithSameID.Element("generalSettings");
                        if (generalSettings != null)
                        {
                            var title = generalSettings.Element("title");
                            var productUrl = generalSettings.Element("productUrl");
                            var categories = generalSettings.Element("categories");
                            if (title.Value != candidateFlashItem.Name)
                                title.Value = candidateFlashItem.Name;
                            if (productUrl.Value != candidateFlashItem.URL)
                                productUrl.Value = candidateFlashItem.URL;
                            if (categories != null)
                            {
                                var category = categories.Element("category");
                                if (category != null)
                                {
                                    var categoryId = category.Element("categoryId");
                                    if (categoryId.Value != candidateFlashItem.Category)
                                        categoryId.Value = candidateFlashItem.Category;
                                }
                            }
                        }
                    }
                    else
                    { 
                        // Hinzugefügt
                        doc.Element("flashlist").Add(
                            new XElement("flash", 
                            new XAttribute("geId", candidateFlashItem.geID), 
                            new XAttribute("geDelete", candidateFlashItem.deleted), 
                            new XElement("generalSettings"), 
                                new XElement("title", candidateFlashItem.Name), 
                                new XElement("productUrl", candidateFlashItem.URL),
                                new XElement("categories", 
                                    new XElement("category", 
                                        new XElement("categoryID", candidateFlashItem.Category)))));
                            
                    }
                }
            });
        }
        doc.Save("Result.xml");
    }

    Gruß
    Marcel

  • Freitag, 27. April 2012 15:00
    Besitzer
     
     

    Hallo LS-Tom,

    Ich gehe davon aus, dass die Antwort Dir weitergeholfen hat.
    Solltest Du noch "Rückfragen" dazu haben, so gib uns bitte Bescheid.

    Grüße,
    Robert


    Robert Breitenhofer, MICROSOFT  Twitter Facebook
    Bitte haben Sie Verständnis dafür, dass im Rahmen dieses Forums, welches auf dem Community-Prinzip „Entwickler helfen Entwickler“ beruht, kein technischer Support geleistet werden kann oder sonst welche garantierten Maßnahmen seitens Microsoft zugesichert werden können.