Einzelne Elemente aus XML-Datei lesen - gibts da nichts in .NET ?

  • VB.NET
  • .NET (FX) 4.5–4.8

Es gibt 4 Antworten in diesem Thema. Der letzte Beitrag () ist von dive26.

    Einzelne Elemente aus XML-Datei lesen - gibts da nichts in .NET ?

    Ich stehe vor folgenden Probel:

    Ich bekomme von einer Webanwendung eine XML-Datei zurück in der verschieden tief geschachtelte Werte stehen. Je nach Abfrage im Onlineshystem kommen mehr oder weniger Daten zurück.

    In der Anlage findet Ihr ein Beispiel-XML aus dem ich folgende Werte auslesen möchte:

    1. <HotelName> <![CDATA[SH2]]> </HotelName> . Dies befindet sich in <HotelDescriptiveContents> <HotelDescriptiveContent ... <HotelInfo..

    2. <GuestRoom Code="7420" ID="7420" MaxAdultOccupancy="1" MaxOccupancy="1" Quantity="3" RoomTypeName="Komfort Einzelzimmer"> . Hier brauche ich den Wert von "Code" oder "ID" (also 7420). Es gibt aber meist mehrere solche Einträge (im Beispiel 3 Stück mit 7420, 7421 und 7422).
    Hier möchte ich folgende Daten für jeden GuestRoom Eintrag auslesen:
    Code (z.B. 7420)
    Quantity (z.B. 3)
    RoomTypeName (z.B. Komfort Einzelzimmer)

    Jetzt kann ich zwar im "Text" nach diversen Zeichenfolgen suchen und dann mit Stringoperationen mich dahinhangeln, aber es sollte für XML (Microsoft stehts sich ja drauf) eine .NET Möglichkeit geben.

    Habt Ihr da einen Tipp für mich?

    PS: Die XML-Datei lässt sich z.B. im Firefox fehlerfrei anzeigen - die Struktur dürfte also in Ordnung sein.
    Dateien
    Liebe Grüße
    Roland Berghöfer

    Meine aktuellen und kostenlos verwendbaren Tools (mit VB.NET erstellt): freeremarkabletools.com | priconman.com | SimpleCalendar | AudibleTouch | BOComponent.com | bonit.at
    Ich habe das mal irgendwann so gelöst.

    VB.NET-Quellcode

    1. Public Sub XMLReader()
    2. Dim strLetztesElement As String = ""
    3. ' Wir benötigen einen XmlReader für das Auslesen der XML-Datei
    4. Dim XMLReader As Xml.XmlReader _
    5. = New Xml.XmlTextReader(strDatei)
    6. ' Es folgt das Auslesen der XML-Datei
    7. With XMLReader
    8. Do While .Read ' Es sind noch Daten vorhanden
    9. ' Welche Art von Daten liegt an?
    10. Select Case .NodeType
    11. ' Ein Element
    12. Case Xml.XmlNodeType.Element
    13. strLetztesElement = .Name
    14. ' Alle Attribute (Name-Wert-Paare) abarbeiten
    15. If .AttributeCount > 0 Then
    16. ' Es sind noch weitere Attribute vorhanden
    17. While .MoveToNextAttribute ' nächstes
    18. 'Console.WriteLine("Feldname: " & .Name & _
    19. '" -> " & _
    20. '"Feldwert: " & .Value)
    21. End While
    22. End If
    23. ' Ein Text
    24. Case Xml.XmlNodeType.Text
    25. Select Case strLetztesElement
    26. Case "TerminalId"
    27. frmSonstigeEinstellungen.txtTerminalId.Text = .Value
    28. Case "Communication"
    29. frmSonstigeEinstellungen.txtCommunication.Text = .Value
    30. Case "IPAdresse"
    31. frmSonstigeEinstellungen.txtIPAdresse.Text = .Value
    32. Case "PortNr"
    33. frmSonstigeEinstellungen.txtPort.Text = .Value
    34. Case "COMPort" 'Lesen wir nicht aus. Wird nicht gebraucht
    35. Case "Databits" 'Lesen wir nicht aus. Wird nicht gebraucht
    36. Case "Parity" 'Lesen wir nicht aus. Wird nicht gebraucht
    37. Case "Stopbits" 'Lesen wir nicht aus. Wird nicht gebraucht
    38. Case "Passwort" 'Lesen wir nicht aus. Wird nicht gebraucht
    39. frmSonstigeEinstellungen.txtKassiererPasswort.Text = .Value
    40. Case "Druckzahlung"
    41. If .Value = "true" Then
    42. frmSonstigeEinstellungen.chkKasseDruckenZahlung.CheckState = CheckState.Checked
    43. Else
    44. frmSonstigeEinstellungen.chkKasseDruckenZahlung.CheckState = CheckState.Unchecked
    45. End If
    46. Case "Betragsanzeige"
    47. If .Value = "true" Then
    48. frmSonstigeEinstellungen.chkBetragsanzeige.CheckState = CheckState.Checked
    49. Else
    50. frmSonstigeEinstellungen.chkBetragsanzeige.CheckState = CheckState.Unchecked
    51. End If
    52. Case "Zwischenstatus"
    53. If .Value = "true" Then
    54. frmSonstigeEinstellungen.chkZwischenstatus.CheckState = CheckState.Checked
    55. Else
    56. frmSonstigeEinstellungen.chkKasseDruckenZahlung.CheckState = CheckState.Unchecked
    57. End If
    58. Case "Druckverwaltung"
    59. If .Value = "true" Then
    60. frmSonstigeEinstellungen.chkKasseDruckenVerwaltung.CheckState = CheckState.Checked
    61. Else
    62. frmSonstigeEinstellungen.chkKasseDruckenVerwaltung.CheckState = CheckState.Unchecked
    63. End If
    64. Case "Zahlungsart"
    65. frmSonstigeEinstellungen.txtZahlungsart.Text = .Value
    66. Case "Trace"
    67. If .Value = "true" Then
    68. frmSonstigeEinstellungen.chkTrace.CheckState = CheckState.Checked
    69. Else
    70. frmSonstigeEinstellungen.chkTrace.CheckState = CheckState.Unchecked
    71. End If
    72. Case "MaxTraceData" 'Lesen wir nicht aus. Wird nicht gebraucht
    73. Case "MaxPaymentData" 'Lesen wir nicht aus. Wird nicht gebraucht
    74. End Select
    75. ' Ein Kommentar
    76. Case Xml.XmlNodeType.Comment
    77. End Select
    78. Loop
    79. .Close() ' XMLTextReader schließen
    80. End With
    Ich täte sehr vom Gemurkel mit XmlReader abraten.
    Die aktuelle Technologie ist Xml.Linq, und die zu verwendenden Klassen heissen XDocument, XElement, XAttribute.
    Aber beschäftige dich auch mit Xml als Sprache.
    Es gibt da Fachbegriffe wie Element, Attribut, Knoten etc. - wenn man da nicht den Sinn von verstanden hat, wird man ziemlich jämmerlich herumstümpern müssen.
    Xml-Tutorial
    Hingegen wenn verstanden, dann kann man eigene Xml-Abfragen formulieren, und Xml zeigt sich dann als eine Art Datenbank.

    Oder du bildest, das was du brauchst als Klassen nach und deserialisierst das ganze. So z.B. wenn du das aus c# übersetzen kannst:

    C#-Quellcode

    1. public class OTA_HotelDescriptiveInfoRS {
    2. public HotelDescriptiveContents HotelDescriptiveContents { get; set; }
    3. }
    4. public class HotelDescriptiveContents {
    5. public HotelDescriptiveContent HotelDescriptiveContent { get; set; }
    6. }
    7. public class HotelDescriptiveContent {
    8. public HotelInfo HotelInfo { get; set; }
    9. public FacilityInfo FacilityInfo { get; set; }
    10. }
    11. public class HotelInfo {
    12. public string HotelName { get; set; }
    13. }
    14. public class FacilityInfo {
    15. public List<GuestRoom> GuestRooms { get; set; }
    16. }
    17. public class GuestRoom {
    18. [XmlAttribute]
    19. public string Code { get; set; }
    20. [XmlAttribute]
    21. public string ID { get; set; }
    22. [XmlAttribute]
    23. public string Quantity { get; set; }
    24. [XmlAttribute]
    25. public string RoomTypeName { get; set; }
    26. }
    27. class Program {
    28. static void Main(string[] args) {
    29. XmlSerializer ser = new XmlSerializer(typeof(OTA_HotelDescriptiveInfoRS), "http://www.opentravel.org/OTA/2003/05");
    30. using (FileStream fs = new FileStream(@"C:\Users\Bluespide\Desktop\HotelDescriptiveInfo.txt.xml", FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) {
    31. OTA_HotelDescriptiveInfoRS hotelDesc = (OTA_HotelDescriptiveInfoRS)ser.Deserialize(fs);
    32. //hotelDesc.HotelDescriptiveContents.HotelDescriptiveContent.HotelInfo.HotelName
    33. //hotelDesc.HotelDescriptiveContents.HotelDescriptiveContent.FacilityInfo.GuestRooms[0].RoomTypeName
    34. //...
    35. }
    36. }
    37. }
    Vielen Dank, Euch allen.
    Ich habe jetzt einen gangbaren Weg über die Mischung verschiedener Techniken gefunden.

    Einerseits über XML und eine Mischung aus XML und Instr().
    Leider wars nicht so einfach, weil in einer Zimmerreservierung (childnode) nicht nur Zimmer einer Kategorie sein können, sondern beliebig viele Zimmer mit verschiedenen Kategorien und auch immer anderen Preisen.

    Daher lese ich zuerst die Childnodes mit den einzelnen Reservierungen aus und gehe dann die Childnodes einem nach dem anderen durch und extrahiere die entsprechenden Infos die ich daraus brauche. Teilweise auch mit Instr() und Mid(). So funktioniert es.

    VB.NET-Quellcode

    1. '1. Zuerst die Reservierungsnodes <HotelReservation>auslesen
    2. If root.HasChildNodes Then
    3. For HauptNodes As Integer = 0 To root.ChildNodes.Count - 1
    4. If root.ChildNodes(HauptNodes).Name.ToUpper = "RESERVATIONSLIST" Then
    5. HRNode = root.ChildNodes(HauptNodes)
    6. 'Hier die einzelnen "HotelReservation" durchgehen, falls vorhanden
    7. If HRNode.HasChildNodes Then
    8. For ReservationNodes As Integer = 0 To HRNode.ChildNodes.Count - 1
    9. HotelReservation_OuterXML_Zaehler += 1
    10. HotelReservation_OuterXML(HotelReservation_OuterXML_Zaehler) = HRNode.ChildNodes(ReservationNodes)
    11. Next ReservationNodes
    12. End If
    13. End If
    14. Next HauptNodes
    15. End If



    VB.NET-Quellcode

    1. 'Alle Reservierungen durchgehen und Daten extrahieren
    2. For i As Integer = 1 To HotelReservation_OuterXML_Zaehler
    3. 'Datum der Buchungserstellung
    4. CreateDateTime = DateTime.Parse(HotelReservation_OuterXML(i).Attributes.GetNamedItem("CreateDateTime").InnerText)
    5. 'Buchungs-ID ermitteln
    6. If HotelReservation_OuterXML(i).HasChildNodes Then
    7. For UnterNodes As Integer = 0 To HotelReservation_OuterXML(i).ChildNodes.Count - 1
    8. 'Buchungs-ID ermitteln
    9. If HotelReservation_OuterXML(i).ChildNodes(UnterNodes).Name.ToUpper = "UNIQUEID" Then
    10. UniqueID = HotelReservation_OuterXML(i).ChildNodes(UnterNodes).Attributes.GetNamedItem("ID").InnerText
    11. End If
    12. 'Roomstays
    13. If HotelReservation_OuterXML(i).ChildNodes(UnterNodes).Name.ToUpper = "ROOMSTAYS" Then
    14. RoomStaysXMLText = HotelReservation_OuterXML(i).ChildNodes(UnterNodes).OuterXml
    15. 'Suchen nach "<RoomType NumberOfUnits"
    16. Dim TempString As String = ""
    17. Dim Startpos As Integer
    18. While InStr(RoomStaysXMLText, "<RoomType NumberOfUnits=") > 0


    (nur ein Ausschnitt aus dem Code).

    Das Ergebnis und die XML-Datei die dem zugrunde lag findet Ihr im Anhang.
    Bilder
    • 05042020203332.jpg

      244,76 kB, 1.170×482, 88 mal angesehen
    Dateien
    Liebe Grüße
    Roland Berghöfer

    Meine aktuellen und kostenlos verwendbaren Tools (mit VB.NET erstellt): freeremarkabletools.com | priconman.com | SimpleCalendar | AudibleTouch | BOComponent.com | bonit.at