Linq2XML

  • VB.NET

Es gibt 10 Antworten in diesem Thema. Der letzte Beitrag () ist von ErfinderDesRades.

    Zur Zeit bin ich dabei, mich in XML-Files-Auslesen einzuarbeiten.
    Leider empfinde ich die Erklärungen die ich dazu finde ziemlich zerstückelt.
    Was ein Kind, Nachfahre, Knoten ist, das kann ich mir natürlich alles vorstellen.
    Aber wie ich innerhalb eines XML-File navigiere, das ist mir noch nicht so ganz klar.

    Am liebsten würde ich auf Daten mittels Linq zugreifen. Aber auch da habe ich noch
    nicht richtig heraus gefunden, wie ich bestimmte Daten finde. Hier mal ein Beispiel:

    XML-Quellcode

    1. <?xml blablabla...
    2. <Probestellen>
    3. <Probestelle>!--QXXXX-->
    4. <Nummer>QXXXX</Nummer>
    5. <Name>XXXX</Name>
    6. <Parameter>
    7. <A>
    8. <Nr1>false</Nr1>
    9. <Nr2>YY</NR2>
    10. </A>
    11. <B>
    12. <Nr1>true</Nr1>
    13. <Nr2>ZZ</NR2>
    14. </B>
    15. </Parameter>
    16. </Probestelle>
    17. <Probestelle>!--QXXXZ-->
    18. <Nummer>QXXXZ</Nummer>
    19. <Name>XXXZ</Name>
    20. <Parameter>
    21. <A>
    22. <Nr1>true</Nr1>
    23. <Nr2>YY</NR2>
    24. </A>
    25. <B>
    26. <Nr1>true</Nr1>
    27. <Nr2>AA</NR2>
    28. </B>
    29. </Parameter>
    30. </Probestelle>
    31. blabla...

    Hier würde ich gerne nach der Probestelle (XXXX) selektieren,
    und als Ergebnis vom Parameter B den zweiten Wert ausgeben also YY

    Wie würde man das in Linq schreiben?

    Lightsource schrieb:

    Hier würde ich gerne nach der Probestelle (XXXX) selektieren,
    und als Ergebnis vom Parameter B den zweiten Wert ausgeben also YY
    Versteh ich nicht.
    "nach der Probestelle (XXXX) selektieren" verstehe ich so, dass du damit die Probestelle meinst, deren <Name>-Element "XXXX" enthält.
    Diese Probestelle weist aber keinen Parameter B auf, der in irgendeiner Weise "YY" enthalten täte.
    Hast du dich mit deiner Aufgabenstellung vertan?

    Weiters scheine n Zeilen #3 und #17 xml-syntaxwidrig: dem > steht kein entsprechendes < gegenüber.
    Vielleicht hatte ich mich nicht exakt genug ausgedrückt:

    Ich wollte nach der "Probestelle" mit dem <Name>XXXX etc. suchen.
    Also:
    Probestellen.Probestelle.Name="XXXX"

    und von dort aus der Parameter(liste) den Abschnitt <B>, den Wert von <Nr2> (Nr2 soll den "zweiten Wert" beinhalten)

    Parameter.B.Nr2

    Deine zweite Aussage verstehe jetzt ich nicht. Aber es ist möglich, dass ich diese Struktur nicht ganz richtig auswendig
    aus dem Kopf hier wiederholen konnte. Trotzdem finde ich nicht was du meinst. Ich denke, es ist der Kommentar
    da habe ich bestimmt das "<" vor dem "!" vergessen. Sorry.
    Dein Xml enthält keine ParameterListe.
    Es gibt nur von <Probestelle> zwei gleichartige Elemente - also eine Liste.
    Alles andere, was da rumfährt sind Unikate.
    Also wenn du möchtest, dass <Parameter> eine Liste von <B> enthalten soll, dann müsste es so heissen:

    XML-Quellcode

    1. <?xml blablabla...
    2. <Probestellen>
    3. <Probestelle><!--QXXXX-->
    4. <Nummer>QXXXX</Nummer>
    5. <Name>XXXX</Name>
    6. <Parameter>
    7. <B>
    8. <Nr1>false</Nr1>
    9. <Nr2>YY</NR2>
    10. </B>
    11. <B>
    12. <Nr1>true</Nr1>
    13. <Nr2>ZZ</NR2>
    14. </B>
    15. </Parameter>
    16. </Probestelle>
    17. <Probestelle><!--QXXXZ-->
    18. <Nummer>QXXXZ</Nummer>
    19. <Name>XXXZ</Name>
    20. <Parameter>
    21. <B>
    22. <Nr1>true</Nr1>
    23. <Nr2>YY</NR2>
    24. </B>
    25. <B>
    26. <Nr1>true</Nr1>
    27. <Nr2>AA</NR2>
    28. </B>
    29. </Parameter>
    30. </Probestelle>
    31. blabla...

    Lightsource schrieb:

    auswendig aus dem Kopf hier wiederholen
    ist schlecht.
    Da geschieht zu leicht - ja eiglich zwangsläufig, dass du ein unbrauchbares Sample zeigst, und dann keine, falsche oder unbrauchbare Antworten bekommst.
    Bitte recherchiere deine realen Original-Daten, und poste ein Beispiel von dene.



    Merke: In Xml entsteht eine Liste dadurch, dass auf derselben Ebene gleiche Elemente auftreten.

    Treten auf einer Ebene verschiedene Elemente auf, so ist das ein kompliziertes Objekt - aber keine Liste.
    Und ein kompliziertes Objekt ist nicht nach einfachen Regeln zu durchsuchen.

    Oder anders: <A/> ist nicht <B/>
    Sondern <A/> und <B/> sind verschiedene Eigenschaften des Objekts.
    So wie meinetwegen Form.Top und Form.Left unterschiedliche Eigenschaften sind.

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „ErfinderDesRades“ ()

    Wenn du mit Linq auf <B> zugreifst bekommst du zunächstmal beide Bs.
    Natürlich kannst du das aussuchen, was den Wert ZZ hat, aber wenn du den Wert vorher schon weisst, wieso suchst du ihn dann überhaupt?
    Also ich zeige mal, wie man alle <B>.<Nr2>-Werte der Probestelle mit der Nummer 'QXXXX' ausgibt:

    VB.NET-Quellcode

    1. Private _XDoc2 As XDocument = <?xml version="1.0" encoding="UTF-8"?>
    2. <Probestellen>
    3. <Probestelle><!--QXXXX-->
    4. <Nummer>QXXXX</Nummer>
    5. <Name>XXXX</Name>
    6. <Parameter>
    7. <B>
    8. <Nr1>false</Nr1>
    9. <Nr2>YY</Nr2>
    10. </B>
    11. <B>
    12. <Nr1>true</Nr1>
    13. <Nr2>ZZ</Nr2>
    14. </B>
    15. </Parameter>
    16. </Probestelle>
    17. <Probestelle><!--QXXXZ-->
    18. <Nummer>QXXXZ</Nummer>
    19. <Name>XXXZ</Name>
    20. <Parameter>
    21. <B>
    22. <Nr1>true</Nr1>
    23. <Nr2>YY</Nr2>
    24. </B>
    25. <B>
    26. <Nr1>true</Nr1>
    27. <Nr2>AA</Nr2>
    28. </B>
    29. </Parameter>
    30. </Probestelle>
    31. </Probestellen>
    32. Private Sub ParseXdoc2()
    33. Dim xel = _XDoc2.<Probestellen>.<Probestelle>.<Nummer>.First(Function(x) x.Value = "QXXXX")
    34. Dim nr2s = xel.Parent.<Parameter>.<B>.<Nr2>
    35. For Each nr2 In nr2s
    36. Console.WriteLine(nr2.Value)
    37. Next
    38. Dim i = 9
    39. End Sub

    ErfinderDesRades schrieb:

    Du hast nun zwei B.Nr2.
    Und zwar je Probestelle (von denen du ja auch zwei hast).


    Ja, darum will ich ja, wie in einer Datenbank über die Probestelle selektieren, und dann schauen, was in B.Nr2 steht.

    Und darum verstehe ich aber dennoch nicht so ganz, warum mein XML nicht wie ein "eindeutiger" Baum aufgebaut sein sollte.
    Dann wären unter Parameter jeweils "A" und als zweiter Parameter "B"
    Somit hätte ich einen eindeutigen Pfad:

    Probestellen.Probestelle.Parameter.A.Nr1
    Probestellen.Probestelle.Parameter.A.Nr2

    Probestellen.Probestelle.Parameter.B.Nr1
    Probestellen.Probestelle.Parameter.B.Nr2
    Hi.

    Und darum verstehe ich aber dennoch nicht so ganz, warum mein XML nicht wie ein "eindeutiger" Baum aufgebaut sein sollte.


    Ist er doch, ich hab ihn angebellt und soger umarmt... :)

    Aber mit LINQ sollte immer eine Iteration genutzt werden.

    Ich schwör viel einfacher als sich mittel SQL-Artiger herangehensweise zu quälen.

    Der Knoten Probestellen hat ja eine Aufzählung der Element von Typ Probestelle, diese einfach in einer For each durchlaufen und das macht das leben sowas von einfach.

    Weil so wie ich das verstanden habe, wurd LINQ genau für diesen zweck (und mehr, wie Bäume umarmen) entwickelt.

    Das very old but good von SQL ist sowas von Nineties...

    Ob ein Knoten/Element vorhanden ist kann mit dem Wort .Any(Function(x) x.Eigenschaft = Eigenschaftswert)

    Also für mich ist eine Probestelle für sich zu behandeln (Objekt), und nicht in den Tiefen des Objekts eigenschaften mittels LINQ zu ermitteln.


    Was passiert, wenn in der XML zweilmal genau das selbe als Eigenschaftwerten drin steht. Also ein gelichwertiges, aber nicht das gleiche Objekt.

    Dann ist in LINQ/XML ja der Eintrag trotzdem eindeutig, wegen der Position in der Auflistung.

    Also folgt daraus: Durchzählen, jedem eine Schultüte aufs Auge drücken und ab in die Schule, die Eltern brauchen etwas Erholung... Uppsie OFFTOPIC...



    Deswegen ist die Betrachtung, das die Eigenschaft "Parameter.A" und "Parameter.B" im Selben Zweig ligen nicht richtig,
    sondern die sind auf der selben Ebene in der Hierarchie. (Urenkel z.B.).

    c.u. Joshi

    Lightsource schrieb:

    Und darum verstehe ich aber dennoch nicht so ganz, warum mein XML nicht wie ein "eindeutiger" Baum aufgebaut sein sollte.
    kannste machen - ich hab nix dagegen.
    Dann handelt es sich aber nicht mehr um das Suchen von irgendetwas, sondern einfach um den Zugriff auf einen bestimmten Wert.
    Ein weiteres Problem besteht darin, dass du ja zwei Probestellen hast.
    Insofern ist der Baum nicht eindeutig, und du musst doch ein bischen suchen.
    Nämlich so, wie in post#6, zeile#33 gezeigt.

    Ja, und wie stellst du dir das mit dem eindeutigen Baum vor?
    Werden da unter <Parameter> immer weiter neue Sachen eingeschachtelt? <A>, <B>, <C>, <D>, <E>, <F>,...?
    Und wenn du dann eben doch darin suchen willst, willst du immer neue Zugriffs-Pfade zusammenbasteln?
    na fiel Fergnügen