xml auslesen und innertext von Attributen Unique machen?

  • VB.NET

Es gibt 6 Antworten in diesem Thema. Der letzte Beitrag () ist von TomWi.

    xml auslesen und innertext von Attributen Unique machen?

    Hallo Formum,

    ich lese eine XML-File aus und ändere alle Attribute("label") so, dass der Innertext immer einen uniquen Inhalt hat.
    Das heißt, ich füge an jedes label ein _UIN und eine Zahl, die sich erhöht, an.

    sieht dann so aus
    label="test_UIN0"
    label="test_UIN1"

    usw.

    hier mein Code mit dem ich das XML auslese und ändere

    VB.NET-Quellcode

    1. Sub MakeUnique()
    2. Dim Iterator As Integer = 0
    3. Dim MainNodes As Xml.XmlNodeList = a3sXml.SelectNodes("//models")
    4. For Each MainNode As Xml.XmlNode In MainNodes
    5. Dim ChilNodes As Xml.XmlNodeList = MainNode.ChildNodes
    6. For Each ChildNode As Xml.XmlNode In ChilNodes
    7. If Not ChildNode.Attributes("label") Is Nothing Then
    8. Dim SubNodeLabel As String = ChildNode.Attributes("label").InnerText
    9. SubNodeLabel = SubNodeLabel & "_UIN" & Iterator
    10. ChildNode.Attributes("label").InnerText = SubNodeLabel
    11. Console.WriteLine(SubNodeLabel)
    12. End If
    13. Iterator += 1
    14. Next ChildNode
    15. Next MainNode
    16. End Sub


    Wenn jetzt aber z.B. ein Label nur 1mal im XML vorkommt, dann möchte ich keine "_UIN" anhängen.
    Also wirklich nur bei Labels, die nicht unique sind.

    wie mache ich das?
    Kann jemand helfen?

    Danke

    Tom
    Also meine Idee wäre folgende:
    Nehmen wir mal an, es sind 10 Nodes
    Dann würde ich sagen, lese das Attribute("label") von Node 1 aus
    schau die Attribute der Nodes 2-10 an
    wenn der Value aus Node 1 nochmal vorkommt, dann mach ein UIN hin
    wenn nicht, dann lass das UIN weg,
    weiter gehts mit Node2
    Attribute auslesen
    Node 3-10 anschauen
    usw.


    Nur weiss ich nicht, wie ich das Codetechnisch umsetzten soll.
    Hat jemand einen Tip für mich?


    Tom
    1. Option Strict ON
    2. Nimm deinen Code, und nimm erstmal Zeilen 8-11 raus, und pack das Iterator += 1 ebenfalls raus (du wirst sehen warum). Außerdem musst du eine List<XmlNode> führen, welche alle Nodes, die Labels sind, beinhalten soll / wird. In diesem If-Block addest du nun den jeweiligen Node in deine List.
    Nach deinem Code kommt nun folgendes:

    VB.NET-Quellcode

    1. If mynodelist.Count > 1 Then
    2. For Each labelnode As Xml.XmlNode in mynodelist
    3. 'Zeilen 8 - 12 wieder hier einfügen
    4. Next
    5. End If

    Und du siehst, dein Iterator brauchst du nicht mehr, da list.Count dasselbe beinhaltet.

    Vollständiger Code

    VB.NET-Quellcode

    1. Sub MakeUnique()
    2. Dim labelnodes As New List(Of Xml.XmlNode)
    3. Dim MainNodes As Xml.XmlNodeList = a3sXml.SelectNodes("//models")
    4. For Each MainNode As Xml.XmlNode In MainNodes
    5. Dim ChilNodes As Xml.XmlNodeList = MainNode.ChildNodes
    6. For Each ChildNode As Xml.XmlNode In ChilNodes
    7. If Not ChildNode.Attributes("label") Is Nothing Then
    8. labelnodes.Add(ChildNode)
    9. End If
    10. Next
    11. Next
    12. If labelnodes.Count > 1 Then
    13. Dim counter As Integer = 0
    14. For labelnode As Xml.XmlNode in labelnodes
    15. Dim SubNodeLabel As String = labelnode.Attributes("label").InnerText
    16. SubNodeLabel &= "_UIN" & counter.ToString()
    17. labelnode.Attributes("label").InnerText = SubNodeLabel
    18. Console.WriteLine(SubNodeLabel)
    19. counter += 1
    20. Next
    21. End If
    22. End Sub

    »There's no need to "teach" atheism. It's the natural result of education without indoctrination.« — Ricky Gervais

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

    Hallo ThePlexian,

    erstmal vielen Dank für deine Hilfe. Hab den Code mal ausprobiert. Leider macht er nicht das was, was ich mir erhofft hatte.
    vielleicht habe ich mich auch nur falsch ausgedrückt.

    hier nochmal zum hoffentlich besseren Verständnis:

    Ich möchte labels, die mehrmals vorkommen, Unique machen.
    Also z.B.
    Childnode1 hat das attribut "label" mit dem Value "Test"
    Childnode2 hat das attribut "label" mit dem Value "Test"
    Childnode3 hat das attribut "label" mit dem Value "Hund"

    ich möchte, dass an das test von childnode2 ein UIN+Zahl angefügt wird, da es den "Test" ja schon beim Chilnode1 gibt.
    beim "Hund" muss nichts angefügt werden, da es den Hund nur einmal gibt.

    Also einfach alle Nodes durchgehen, schauen ob sie das Attribut "label" haben,
    wenn ja, dann das label auslesen. Wenn ein Inhalt von einem label bei einem anderen Childnode nochmal vorkommt, dann ein UIN an das label anfügen. Aber nicht an das erste label, sondern an das, welches den gleichen inhalt hat, wie das erste label.
    Wenn es das label nur einmal gibt, dann nichts machen.
    hier mal ein kleiner Auszug aus dem XML

    XML-Quellcode

    1. <group msh="1" name="r.apf:z.apf:o.apf:1.apf:userGroup(8)" label="LL">
    2. <child node="r.apf:z.apf:userGroup">
    3. </child>
    4. <child node="r.apf:z.apf:o.apf:1.apf:userGroup(17)">
    5. </child>
    6. <child node="r.apf:z.apf:o.apf:1.apf:userGroup(30)">
    7. </child>
    8. <child node="::userGroup[2]">
    9. </child>
    10. </group>
    11. <group msh="1" name="r.apf:z.apf:o.apf:1.apf:userGroup(8)" label="EXT">
    12. <child node="r.apf:z.apf:userGroup">
    13. </child>
    14. <child node="r.apf:z.apf:o.apf:1.apf:userGroup(17)">
    15. </child>
    16. <child node="r.apf:z.apf:o.apf:1.apf:userGroup(30)">
    17. </child>
    18. <child node="::userGroup[2]">
    19. </child>
    20. </group>
    21. <group msh="1" name="r.apf:z.apf:o.apf:1.apf:userGroup(8)" label="LL">
    22. <child node="r.apf:z.apf:userGroup">
    23. </child>
    24. <child node="r.apf:z.apf:o.apf:1.apf:userGroup(17)">
    25. </child>
    26. <child node="r.apf:z.apf:o.apf:1.apf:userGroup(30)">
    27. </child>
    28. <child node="::userGroup[2]">
    29. </child>
    30. </group>


    hier hab ich jetzt 3 Labels
    label1 hat LL als value
    label2 hat EXT als value
    label3 hat wieder LL als value

    und so soll es am schluss aussehen
    label1"LL"
    label2"EXT"
    label3"LL_UIN0"

    ich hoffe ich habe es jetzt einigermaßen deutlich machen können, was ich brauche.
    Vielen Dank an alle, die mich hierbei unterstützen.

    Tom
    Ah okay, ich dachte es ginge generell um labels.

    Schau dir das mal an:
    Spoiler anzeigen

    C#-Quellcode

    1. static void Main(string[] args)
    2. {
    3. List<string> list = new List<string> { "A", "B", "C", "A", "C", "A", "B", "D", "A", "C", "Y" , "D" };
    4. list = list.OrderBy(s => s).ToList(); //Sortieren wenn gewünscht
    5. Console.WriteLine("Vorher: " + string.Join(" ", list));
    6. foreach (var group in list.GroupBy(s => s)) //Liste wird in gruppen geteilt (hier sind die Keys "A", "B" und "C")
    7. {
    8. if (group.Count() > 1) //Wenn öfters vorhanden
    9. {
    10. int occourences = 0;
    11. for (int i = 0; i <= list.Count() - 1; i++) //Alle Elemente der Liste durchgehen
    12. {
    13. if (list[i] == group.Key) //Wenn der momentane Eintrag in der Liste dem momentanen Key der Gruppe gleich ist
    14. {
    15. if(occourences!=0) //Wenn es nicht mehr der erste Eintrag ist, ändern
    16. list[i] += occourences.ToString();
    17. occourences++; //Counter erhöhen
    18. }
    19. }
    20. }
    21. }
    22. Console.WriteLine("Nachher: " + string.Join(" ", list));
    23. Console.ReadLine();
    24. }
    Bilder
    • sdf.JPG

      27,76 kB, 677×342, 152 mal angesehen
    »There's no need to "teach" atheism. It's the natural result of education without indoctrination.« — Ricky Gervais