none
LinQ - XML Datei auslesen, wie am besten, wenn es gleiche Name gibt. RRS feed

  • Frage

  • Hallo,

    ich möchte es verstanden haben, deshalb frage ich nochmals.

    Wenn mehrere Namen mehrmals vorkommen, geht

    Descendants 

    nicht. Kann das sein?

    Oder liegt es an var ?

    Verwende ich ein Objekt, Klasse erhalte ich Ergebnisse.

    Wobei ich den Pfad korrekt angeben muss!!

    var itemData = from item in feedXML.Descendants("item")

    Hier kann ich keinen Pfad angeben. values/item..?

    private void btnReadXML_Click(object sender, EventArgs e)
            {
                XDocument feedXML = XDocument.Load(@"..\..\TelegramLog\ToParse.xml");
    
                var itemData = from item in feedXML.Descendants("item")
                               where (bool)item.Attribute("MacheWas")
                               select new
                               {
                                   pos = (int)item.Attribute("pos"),
                                   id = (string)item.Attribute("id")
                               };
    
                var list = (from item in feedXML.Element("root").Element("body").Element("structArrays").Element("array").Element("values").Elements("item")
                            where (bool)item.Attribute("MacheWas")
                            select new
                            {
                                Pos = (int)item.Attribute("pos"),
                                ID = (string)item.Attribute("id")
                            });
    
                //using System.Xml.XPath;
                var list2 = (from item in feedXML.XPathSelectElements("root/body/structArrays/array/values/item")
                            // where (bool)item.Attribute("MacheWas")
                                          select new 
                                          {
                                              Pos3 = (int)item.Attribute("pos"),
                                              ID3 = (string)item.Attribute("id")
                                          });
    
    
                List<Bearbeitung> list3 = (from item in feedXML.Element("root").Element("body").Element("structArrays").Element("array").Element("values").Elements("item")
                            where (bool)item.Attribute("MacheWas")
                            select new  Bearbeitung()
                            {
                                pos = (int)item.Attribute("pos"),
                                id = (string)item.Attribute("id")
                            }).ToList();
    
                //using System.Xml.XPath;
                List<Bearbeitung> list4 = (from item in feedXML.XPathSelectElements("root/body/structArrays/array/values/item")
                                           // where (bool)item.Attribute("MacheWas")
                                           select new Bearbeitung()
                                           {
                                               pos = (int)item.Attribute("pos"),
                                               id = (string)item.Attribute("id")
                                           }).ToList();
    
    
    
                string id = feedXML.Descendants("item").First(i => (int)i.Attribute("pos") == 5).Attribute("id").Value;
    // GEHT NICHT!!
    
                XElement values = feedXML.Descendants("values").FirstOrDefault();
                values.Add(
                new XElement("item",
                  new XAttribute("pos", 99),
                  new XAttribute("id", "KB00B0013711000-01"),
                  new XAttribute("MacheWas", true)
                  //new XAttribute("Bearbeitung", 0)
                ));
    
                feedXML.Save(@"..\..\TelegramLog\ToParseNEU.xml");
    
                var valuesChild = from child3 in feedXML.Root.Elements("Child3")
                             select child3.Value;

    Danke für Tipps.

    Siehe Bilder.

    Grüße Andreas

    Wie würde man array name (Element 1 Attribut) auslesen?


    Montag, 26. März 2012 13:57

Antworten

  • Mit "var" wird der Typ der Variablen vom Compiler abgeleitet, was im Falle von

      select new { ... }

    auch nötig ist, da dabei vom Compiler ein anonymer Typ erzeugt wird, den man im Code nicht selbst benennen kann.

    Ansonsten gibt eine LINQ-Abfrage mit

      from ... select

    ein IEnumerable<T> zurück, wobei T dann in dem Beispiel halt der anonyme Typ ist.

    Wo/wie verwendest du denn "list2" weiter, welches Problem gibt es damit? Ein IEnumerable<T> muss erst per foreach oder ähnlichem abgearbeitet werden, siehe http://msdn.microsoft.com/en-us/library/bb397906.aspx.

    Ein wesentlicher Unterschied zum folgenden Beispiel ist, dass in diesem die Anfrage

      from ... select ...

    in ein

      (from ... select ...).ToList()

    geklammert wird, so dass man dann nicht mehr ein IEnumerable<T> erhält, sondern List<T>. So du "list2" als Quelle für Datenbindung oder ähnliches verwendest, hilft es also eventuell, auch bei

     var list2 = (from ... select new { ... }).ToList();

    zu verwenden.


    MVP Data Platform Development My blog

    Montag, 26. März 2012 16:18

Alle Antworten

  • Wenn du an verschiedenen Stellen im Dokument Elemente mit dem Namen "item" hast, dann findet

      doc.Descendants("item")

    alle davon an allen Stellen. So du nur an einer bestimmten Stelle suchst, musst du halt den Pfad dahin konstruieren, also entweder mit den LINQ to XML Methoden Element("...") bzw. Elements("...") oder mit XPath und den Methoden XPathSelectElement bzw. XPathSelectElements.


    MVP Data Platform Development My blog

    Montag, 26. März 2012 14:25
  • Hallo Martin,

    OK fast alles.
    Ich finde Deinen Ansatz super, mit var.
    Das andere klappt.
    Müsste ich für var list2 nicht was zurück bekommen?

    Da erhalte ich eben nichts. Pfade stimmen.

    Exception wird ausgelöst, es wird nicht angezeigt aber woran es hängt, sehe ich das richtig?

    Ich hätte erwartet, dass die Exception

    nameNoExist   

    anzeigt, oder?

    Grüße Andreas

    --

    public class Bearbeitung
            {
                public int pos;
                public string id;
            }
    		
    	 // Das ist NIO
         var list2 = (from item in feedXML.XPathSelectElements("root/body/structArrays/array/values/item")
                            // where (bool)item.Attribute("MacheWas")
                                          select new 
                                          {
                                              Pos3 = (int)item.Attribute("pos"),
                                              ID3 = (string)item.Attribute("id")
                                          });
    									  
    	 // Das ist IO
    	    List<Bearbeitung> list4 = (from item in feedXML.XPathSelectElements("root/body/structArrays/array/values/item")
                                           // where (bool)item.Attribute("MacheWas")
                                           select new Bearbeitung()
                                           {
                                               pos = (int)item.Attribute("pos"),
                                               id = (string)item.Attribute("id")
                                           }).ToList();
    	 // Das verstehe ich nicht.
    	 // var ist mal eine Art template, muss ja auf Einträge aufweisen, oder?
    	 // da kommt nichts zurück, obwohl der Pfad stimmt.
    	 
    	
                try
                {
    
                    string valueChild = (string)feedXML.Root.Element("Child3");
                    string valueArray1 = (string)feedXML.XPathSelectElement("root/body/structArrays/array").FirstAttribute.Value;
                    string valueArray2 = (string)feedXML.XPathSelectElement("root/body/structArrays/array").Attribute("name").Value;
                    // string valueArray3 = (string)feedXML.XPathSelectElement("root/body/structArrays/array").Attribute("nameNoExist").Value;   
                    // wenn nicht da Exception
                    //string id = feedXML.Descendants("item").First(i => (int)i.Attribute("pos") == 5).Attribute("id").Value;
                    string id = feedXML.XPathSelectElements("root/body/structArrays/array/values/item").First(i => (int)i.Attribute("pos") == 5).Attribute("id").Value;
    
                }
                catch (Exception exMy)
                {
                    Trace.WriteLine(exMy.Message);
                }
    

    Montag, 26. März 2012 15:21
  • Mit "var" wird der Typ der Variablen vom Compiler abgeleitet, was im Falle von

      select new { ... }

    auch nötig ist, da dabei vom Compiler ein anonymer Typ erzeugt wird, den man im Code nicht selbst benennen kann.

    Ansonsten gibt eine LINQ-Abfrage mit

      from ... select

    ein IEnumerable<T> zurück, wobei T dann in dem Beispiel halt der anonyme Typ ist.

    Wo/wie verwendest du denn "list2" weiter, welches Problem gibt es damit? Ein IEnumerable<T> muss erst per foreach oder ähnlichem abgearbeitet werden, siehe http://msdn.microsoft.com/en-us/library/bb397906.aspx.

    Ein wesentlicher Unterschied zum folgenden Beispiel ist, dass in diesem die Anfrage

      from ... select ...

    in ein

      (from ... select ...).ToList()

    geklammert wird, so dass man dann nicht mehr ein IEnumerable<T> erhält, sondern List<T>. So du "list2" als Quelle für Datenbindung oder ähnliches verwendest, hilft es also eventuell, auch bei

     var list2 = (from ... select new { ... }).ToList();

    zu verwenden.


    MVP Data Platform Development My blog

    Montag, 26. März 2012 16:18