XDocument: Element anhand seiner Attribute auswählen

  • VB.NET

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

    XDocument: Element anhand seiner Attribute auswählen

    Ich stehe momentan vor einem kleinen Problem, bei dem ich einfach keinen vernünftigen Ansatz finden kann. Vllt. hat ja hier einer eine gute Idee ;)
    Ich verwende die XDocument-Klasse um eine XML-Dokument einzulesen und dann im Programm zu verwenden. Das auslesen von Werten, die Knoten/Elementen untergeordnet sind klappt wunderbar, selbes gilt für Attribute. Das Problem ist nun das folgende: In der XML-Datei finden sich unter dem Knoten A meinetwegen 4 Elemte B, die je 2 verschiedene Attribute haben (x und y) sowie einen untergeordneten Wert (z). Die 4 Bs lassen sich anhand von x und y eindeutig unterscheiden. Im Prinzip also so:

    XML-Quellcode

    1. <A>
    2. <B x="1" y="1">1</B>
    3. <B x="2" y="1">2</B>
    4. <B x="1" y="2">3</B>
    5. <B x="2" y="2">4</B>
    6. </A>

    Was nun passieren soll ist, das in ein 2-dimensionales Array alle z-Werte eingespeist werden, und zwar immer an die Position x, y.
    Mein Anfang sieht bisher so aus, dass ich mit 2 verschachtelten for-Schleifen die Variablen x1 und y1 im Programm so verändere, dass sie systematisch jede Kombination einmal annehmen. Also so:

    VB.NET-Quellcode

    1. For y1 As Integer = 1 To 'Bekannter, größter Wert, den y im Dokument annimmt.
    2. For x1 As Integer = 1 To 'Bekannter, größter Wert, den x im Dokument annimmt.
    3. Next
    4. Next

    In der freien Stelle in der Mitte muss jetzt "nur" noch aus dem bereits eingelesen Dokument genau das B gesucht werden, das als Attribute sowohl x1 als x und y1 als y beinhaltet. Und genau ist das ist das Problem. Wie kann man das eine B anhand seiner attribute herausfiltern und den untergeordneten Wert verwenden?
    Warscheinlich kommt man weiter, in dem man sich mit der .Elements-Methode alle untergeeordneten Elemente von A holt, also die Bs, und die dann Stück für Stück auseinander nimmt.

    Hoffe mir kann jemand helfen, danke schonmal im Vorraus.



    Mfg, jmb.96 :)



    EDIT: Wortfehler korrigiert
    "People assume that time is a strict progression of cause to effect, but actually, from a non-linear, non-subjective viewpoint, it's more like a big ball of wibbly wobbly, ...timey wimey ...stuff."

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „jmb.96“ ()

    Da hab ich wohl die Wörter verwechselt, aber egal. Was ich brauche ist im Prinzip eine Möglichkeit, den untergeordneten Wert von einem Element mit eben dem bestimmten Attribut (Ha, diesmal wars richtig :D ), oder halt auch zwei, auszulesen. Das Problem also wie man das per

    VB.NET-Quellcode

    1. Dokument.<Element>.@Attribut

    ermittelte B an das Auslesen des untergeordneten Values übergibt.
    Mir fehlt einfach ein Punkt an dem ich ansetzten kann.


    Mfg, jmb.96 :)
    "People assume that time is a strict progression of cause to effect, but actually, from a non-linear, non-subjective viewpoint, it's more like a big ball of wibbly wobbly, ...timey wimey ...stuff."

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „jmb.96“ ()

    Im Prinzip bräuchte ich eine Variable, die genau EIN B speichert. Die könnte man dann von allen Seiten beliebig durchleuchten und auslesen. Verwendet man den allgemeinen XDocument-Verweis auf das B, so kann ja jedes Mal ein beliebeiges B gesucht werden, und beim Auslesen würden mehrere Werte herauskommen. Daher ist also folgendes Sinnlos:

    VB.NET-Quellcode

    1. For y1 As Integer = 1 To 'Bekannter, größter Wert, den y im Dokument annimmt.
    2. For x1 As Integer = 1 To 'Bekannter, größter Wert, den x im Dokument annimmt.
    3. If BlaDoc.<A>.<B>.Attributes.Contains(New XAttribute("x", x1)) And BlaDoc.<A>.<B>.Attributes.Contains(New XAttribute("y", y1)) Then
    4. BlaArray(x1, y1) = CInt(BlaDoc.<A>.<B>.Value)
    5. End If
    6. Next
    7. Next

    Man müsste alle BlaDoc.<A>.<B> durch diese entsprechende Varibale ersetzen.
    Vielleicht gibt es da ja sogar eine entsprechende Möglichkeit. Falls jemand eine Idee hat, schon mal danke im Vorraus ;) .



    Mfg, jmb.96 :)
    "People assume that time is a strict progression of cause to effect, but actually, from a non-linear, non-subjective viewpoint, it's more like a big ball of wibbly wobbly, ...timey wimey ...stuff."

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „jmb.96“ ()

    VB.NET-Quellcode

    1. for each Xel in AxElement
    2. dim x= Integer.Parse(Xel.@x)
    3. dim y= Integer.Parse(Xel.@y)
    4. dim value = Integer.Parse(Xel.Value)
    5. myArray(y, x)=value
    6. Next
    so ungefähr.
    Halt nicht dein 2-dim Array mit verschachtelter Schleife durchlaufen, sondern die XElemente einfach straight forward.
    Man kann das einfach mit

    VB.NET-Quellcode

    1. for each einXElemet in nocheinXElement

    abfragen?

    /AFK Kopf gegen die Wand schlagen



    Mfg, jmb.96 :)

    EDIT:
    Damit alles fehlerfrei klappt muss man sich die Auflistung mit XEl.Elements holen.
    Wenn man das ganze dann noch ein bisschen kürzt sieht es so aus und funzt ;) :

    VB.NET-Quellcode

    1. For Each AktB As XElement In BlaDoc.<A>.Elements
    2. BlaArray(CInt(AktB.@x), CInt(AktB.@y)) = CInt(AktB.Value)
    3. Next

    Nochmal ein riesiges Danke! ^^
    "People assume that time is a strict progression of cause to effect, but actually, from a non-linear, non-subjective viewpoint, it's more like a big ball of wibbly wobbly, ...timey wimey ...stuff."

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „jmb.96“ ()

    ----
    So, das Thema ist eigendlich ja schon gelöst und recht alt, aber es hat sich ein neues Problem aufgetan:
    Versucht man, den kompletten Vorgang umzukehren, also das Array ins Dokument zu quetschen, muss man wohl oder übel ein XElemnet heraussortieren. Würde man nur alles verdrehen, also so:

    VB.NET-Quellcode

    1. For Each AktB As XElement In BlaDoc.<A>.Elements
    2. AktB.Value = CStr(BlaArray(CInt(AktB.@x), CInt(AktB.@y)))
    3. Next

    , so wird zwar der korrekte Wert natürlich in AktB eingespeist, aber AktB nicht in das entsprechende Element des Dokumentes.
    Man müsste also das entsprechende Element auswählen und mit dem aktuellen AktB synchronisieren. Womit man wieder bei dem im Startthread beschriebenen Problem wäre, bei dem ich verzweifle.

    Hat vielleicht jemand noch eine Idee?


    Mfg, jmb.96 :)
    "People assume that time is a strict progression of cause to effect, but actually, from a non-linear, non-subjective viewpoint, it's more like a big ball of wibbly wobbly, ...timey wimey ...stuff."
    Nein, das Dokument exestiert bereits. Im Prinzip handlet es sich um um den gleichen Vorgang wie im ersten Thread, nur das ich nicht die Inhalte aus einem (exestierenden, befüllten) XDocument in ein (exestierendes) Array speichern will, sondern we o. g. genau anders herum die Inhalte aus einem (exestirenden, befüllten) Array in ein ((mit kompletter Struktur) exestierendes) XDocument einspeisen will. Bei der Struktur etc. handelt es sich um exakt das gleiche wie im Startthread.
    In die eine Richtung man mit der Lösung aus Post 5/6 mit der For-Schleife immer ein Element aus dem XDocument nehmen, und anhand seiner Daten in das Array einordnen. Verucht man das jedoch umzukehren, wird -wie oben bereits beschrieben- die "Zähler"-Variable, (sie zählt zwar nicht in diesem Sinne, aber ich nenne sie jetzt einfach mal so, gemeint ist das "AktB"), nicht in das XDocument geschrieben. Und ich weis nicht, wie ich das hinbekommen soll, s. oben.


    Mfg, jmb.96 :)
    "People assume that time is a strict progression of cause to effect, but actually, from a non-linear, non-subjective viewpoint, it's more like a big ball of wibbly wobbly, ...timey wimey ...stuff."

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „jmb.96“ ()

    Eigentlich müsste das ja gar nicht so schwierig sein, warscheinlich bin ich mal wieder völlig auf dem Holzweg. Hat wirklich keiner eine Idee?


    Mfg, jmb.96 :)
    "People assume that time is a strict progression of cause to effect, but actually, from a non-linear, non-subjective viewpoint, it's more like a big ball of wibbly wobbly, ...timey wimey ...stuff."
    Geanu den Ansatz hatte ich ja anfangs, siehe:

    jmb.96 schrieb:



    VB.NET-Quellcode

    1. For y1 As Integer = 1 To 'Bekannter, größter Wert, den y im Dokument annimmt.
    2. For x1 As Integer = 1 To 'Bekannter, größter Wert, den x im Dokument annimmt.
    3. Next
    4. Next



    In der freien Stelle in der Mitte muss jetzt "nur" noch aus dem bereits eingelesen Dokument genau das B gesucht werden, das als Attribute sowohl x1 als x und y1 als y beinhaltet. Und genau ist das ist das Problem. Wie kann man das eine B anhand seiner attribute herausfiltern und den untergeordneten Wert verwenden?
    Warscheinlich kommt man weiter, in dem man sich mit der .Elements-Methode alle untergeeordneten Elemente von A holt, also die Bs, und die dann Stück für Stück auseinander nimmt.

    Nur gibt es hier eben die Komplikation, das man innerhalb der Schleife nicht das eine "b" auswählen kann, so das man bei allen Verweisen darauf immer das gleiche Element gemeint ist. Desshalb gab es ja bei der Lösung des ersten Problems den "Zähler", der auf immer genau ein Element verwiesen hat. Nur funktioniert das natürlich -siehe oben- andersherum nicht mehr.


    Mfg, jmb.96 :)
    "People assume that time is a strict progression of cause to effect, but actually, from a non-linear, non-subjective viewpoint, it's more like a big ball of wibbly wobbly, ...timey wimey ...stuff."
    Das hab ich mich ja auch gefragt, s. zichmal oben :D
    Das war ja auch nur ein Ansatz. Aber wie soll es dann gehen?

    Mfg, jmb.96 :)
    "People assume that time is a strict progression of cause to effect, but actually, from a non-linear, non-subjective viewpoint, it's more like a big ball of wibbly wobbly, ...timey wimey ...stuff."
    siehe post#13

    naja - mal vorgekaut, weil XElements sind schon lustig:

    VB.NET-Quellcode

    1. Public Class XelTests
    2. Private Shared XDoc As XElement = <C>
    3. <A>
    4. <B x="1" y="1">1</B>
    5. <B x="2" y="1">2</B>
    6. <B x="1" y="2">3</B>
    7. <B x="2" y="2">4</B>
    8. </A>
    9. <A>
    10. <B x="0" y="0">5</B>
    11. <B x="0" y="1">6</B>
    12. <B x="0" y="2">7</B>
    13. <B x="1" y="0">8</B>
    14. <B x="2" y="0">9</B>
    15. </A></C>
    16. Public Shared Sub Main()
    17. Dim elements = XDoc.<A>.<B>
    18. Dim arr(2, 2) As String
    19. For Each el In elements
    20. arr(Integer.Parse(el.@x), Integer.Parse(el.@y)) = el.Value
    21. Next
    22. End Sub
    23. End Class

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

    Vorgekau wollte ichs zwar gar nicht, aber trotzdem danke ;)

    @Topic: Diese Richtung hatten wir schon: siehe Post 5/6. Was ich machen will, ist ja den Inhalt des Arrays ins XDocument zu übertragen, nicht andersherum.

    Mfg, jmb.96 :)
    "People assume that time is a strict progression of cause to effect, but actually, from a non-linear, non-subjective viewpoint, it's more like a big ball of wibbly wobbly, ...timey wimey ...stuff."