XML zu CSV: Datei nicht vollständig

  • VB.NET

Es gibt 8 Antworten in diesem Thema. Der letzte Beitrag () ist von Translating-IT.

    XML zu CSV: Datei nicht vollständig

    Hallo,

    nach seeeeehr langer Zwangsprogrammierpause, hab ich wieder was programmiert, aber leider ist das Ergebnis nicht ganz wie gewünscht.

    Ich lese eine 1,4 GB (tendenz steigend) große XML-Datei aus und schreibe gewissen Elemente und Attribute in eine CSV-Datei. Das klappt an sich schon ganz gut, aber leider werden die letzten Zeilen nicht mehr vollständig ausgelesen bzw. in CSV gespeichert. Meist ist eine Zeile irgendwo mittendrin abgeschnitten und die Datei hört dort auf. Das ist das erste Mal, dass ich mit XML und CSV arbeite.

    Nur zur Info: Ich weiß, dass XML auch von Excel und Co. recht gut ausgelesen werden kann, aber hier ist CSV zwingend erforderlich, da nicht nur in diesen Programmen damit gearbeitet wird und auch Laien recht schnell zu einer Tabelle kommen sollen, ohne allzuviel rumfrickeln zu müssen, also bitte keine Antworten à la "lass doch einfach alles in XML".

    Ich gehe mal davon aus, dass der Speicher überlastet wird, und daher die Daten abgeschnitten werden. Ich habe schon versucht mit "Using" zu arbeiten, hat auch nicht viel gebracht. Die CSV-Befehle benötigen keine extra Flush-Zeile, da der letzte Befehl im Loop diesen automatisch ausführt.

    Es dürfte also am Stream der XML-Datei liegen, den zu flushen, habe ich auch schon mal versucht. Hat auch nichts gebracht, da war die Datei dann auf einmal viel kleiner als sie sein sollte, oder hab ich da was falsch gemacht. Was habe ich da übersehen? Ich suche schon seit einer Woche im Netz.

    Anbei den Code:

    VB.NET-Quellcode

    1. Imports System.Xml
    2. Imports CsvHelper
    3. Imports System.IO
    4. Partial Class lu_lod
    5. Inherits subs
    6. Function xmltocsv()
    7. Dim WorkingFolder = Server.MapPath("")
    8. Dim TextWriter = File.CreateText("\translating-it.eu\wwwroot\Admin\lod.csv")
    9. Dim xmlfile = Path.Combine(WorkingFolder, "lod-opendata.xml")
    10. Dim csvwriter As New CsvWriter(TextWriter, Globalization.CultureInfo.CurrentCulture)
    11. Dim str_item As String
    12. Dim str_variantcorrect As String
    13. Dim str_pluriel As String
    14. Dim str_pluriel2 As String
    15. Dim boo_varianteh As Boolean
    16. Dim boo_variantel As Boolean
    17. Dim boo_varianteo As Boolean
    18. Dim readxml As XmlReader = XmlReader.Create(xmlfile)
    19. While readxml.Read
    20. If readxml.IsStartElement Then
    21. If readxml.Name = "lod:ITEM-ADRESSE" Then
    22. If readxml.Read() Then
    23. str_item = readxml.Value
    24. End If
    25. End If
    26. If readxml.Name = "lod:FORME-PLURIEL" Then
    27. If readxml.Read() Then
    28. str_pluriel = readxml.Value
    29. End If
    30. End If
    31. If readxml.Name = "lod:FORME-PLURIEL" And str_pluriel <> "" Then
    32. If readxml.Read() Then
    33. str_pluriel2 = readxml.Value
    34. End If
    35. End If
    36. If readxml.Name = "lod:RENVOI-ADJ" Then
    37. str_variantcorrect = readxml("lod:ID-ITEM-ADRESSE")
    38. End If
    39. If readxml.Name = "lod:RENVOI-ADV" Then
    40. str_variantcorrect = readxml("lod:ID-ITEM-ADRESSE")
    41. End If
    42. If readxml.Name = "lod:RENVOI-ART" Then
    43. str_variantcorrect = readxml("lod:ID-ITEM-ADRESSE")
    44. End If
    45. If readxml.Name = "lod:RENVOI-CONJ" Then
    46. str_variantcorrect = readxml("lod:ID-ITEM-ADRESSE")
    47. End If
    48. If readxml.Name = "lod:RENVOI-ET-TRAIT-LING-SUPPL-SUBST" Then
    49. str_variantcorrect = readxml("lod:ID-ITEM-ADRESSE")
    50. End If
    51. If readxml.Name = "lod:RENVOI-INT" Then
    52. str_variantcorrect = readxml("lod:ID-ITEM-ADRESSE")
    53. End If
    54. If readxml.Name = "lod:RENVOI-PART" Then
    55. str_variantcorrect = readxml("lod:ID-ITEM-ADRESSE")
    56. End If
    57. If readxml.Name = "lod:RENVOI-PREP" Then
    58. str_variantcorrect = readxml("lod:ID-ITEM-ADRESSE")
    59. End If
    60. If readxml.Name = "lod:RENVOI-PRON" Then
    61. str_variantcorrect = readxml("lod:ID-ITEM-ADRESSE")
    62. End If
    63. If readxml.Name = "lod:RENVOI-SUBST" Then
    64. str_variantcorrect = readxml("lod:ID-ITEM-ADRESSE")
    65. End If
    66. If readxml.Name = "lod:RENVOI-VRB" Then
    67. str_variantcorrect = readxml("lod:ID-ITEM-ADRESSE")
    68. End If
    69. If readxml.Name = "lod:VARIANTE-HOMOSEME" Then
    70. boo_varianteh = True
    71. End If
    72. If readxml.Name = "lod:VARIANTE-LOCALE" Then
    73. boo_variantel = True
    74. End If
    75. If readxml.Name = "lod:VARIANTE-ORTHOGRAPHIQUE" Then
    76. boo_varianteo = True
    77. End If
    78. End If
    79. If readxml.NodeType = XmlNodeType.EndElement Then
    80. If readxml.Name = "lod:ITEM" Then
    81. csvwriter.WriteField(str_item)
    82. csvwriter.WriteField(str_pluriel)
    83. csvwriter.WriteField(str_pluriel2)
    84. csvwriter.WriteField(str_variantcorrect)
    85. csvwriter.WriteField(boo_varianteh)
    86. csvwriter.WriteField(boo_variantel)
    87. csvwriter.WriteField(boo_varianteo)
    88. csvwriter.NextRecord()
    89. boo_varianteh = False
    90. boo_variantel = False
    91. boo_varianteo = False
    92. str_item = ""
    93. str_variantcorrect = ""
    94. str_pluriel = ""
    95. str_pluriel2 = ""
    96. End If
    97. End If
    98. End While
    99. End Function
    100. End Class


    LG,
    Pascal

    *Topic verschoben*
    :!: Leider hab ich nicht immer Zeit zum Programmieren, da es eher ein Hobby ist. Falls ich mal im Forum ne Frage stelle und länger nicht antworte, nicht böse sein: Ich bin dann entweder beruflich oder mit der Familie zu sehr eingespannt oder einfach zu müde. Das kann erfahrungsgemäß auch mal über Wochen dauern, aber ich melde mich immer und setze die Frage ggf. auf beantwortet.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Marcus Gräfe“ ()

    @Translating-IT Klassischer Fall für das Debugging:
    Setze nen Haltepunkt drauf und analysiere, was Dein Programm tut:
    Debuggen, Fehler finden und beseitigen
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    VB-Fragen über PN / Konversation werden ignoriert!
    Hallo Rod,

    Debugging schön und gut, aber soll ich ca. ne Million mal auf Weiter klicken, denn auf das läuft es in etwa hinaus? Wenn es bei einem der ersten Durchläufe passieren würde, wäre es kein Problem rauszufinden, wo und wann. Nur hier dauert eine automatisiert Abfrage und Umwandlung schon bis zu 20 Minuten, bei manuellem Weiterklicken, wohl noch viel länger.

    Es passiert ja erst gegen Ende von sehr großen Dateien und nicht bei kleinen Dateien. Je größer die Datei bzw. je mehr Daten ich in die CSV schreibe, umso früher in den Zeilen wird aufgehört zu schreiben. Es ist mit ziemlicher Sicherheit der Arbeitsspeicher, der das Problem verursacht. In den meisten Foren stoße ich auf Flush-Probleme, ich habe versucht die Flush-Befehle für den Stream einzubauen, nur hat er mir dann die Datei nur mehr mit den paar letzten Einträgen der XML-Datei befüllt, der Rest war weg.

    Ich muss den genauen Code zu Flush nochmal morgen auf meinem anderen Rechner raussuchen, den habe ich hier nicht zur Verfügung.

    Edit: die Voraussetzungen am PC bei einem Debugging wäre auch nicht dieselben wie am Server, wo die Umwandlung durchgeführt wird: 8 Kerne (16 logische Prozesoren mit 16 GB Ram vs. 2 Kernen (4 log. Proz.) mit 24 GB Ram (wovon derweil knapp 4,x GB für meine virtuellen Server direkt freigegeben sind)

    LG
    :!: Leider hab ich nicht immer Zeit zum Programmieren, da es eher ein Hobby ist. Falls ich mal im Forum ne Frage stelle und länger nicht antworte, nicht böse sein: Ich bin dann entweder beruflich oder mit der Familie zu sehr eingespannt oder einfach zu müde. Das kann erfahrungsgemäß auch mal über Wochen dauern, aber ich melde mich immer und setze die Frage ggf. auf beantwortet.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Translating-IT“ ()

    @Translating-IT Dann musst Du Dir einen geeigneten Soft-BreakPoint setzen:
    Fehler finden und Fehler vermeiden mit Debug.Assert(AUSDRUCK)
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    VB-Fragen über PN / Konversation werden ignoriert!
    der gezeigte Code sieht mir nicht danach aus, dass er SpeicherProbleme verursachen würde.
    Weil da wird mit Streams gearbeitet, und Streams sind grade dafür erfunden, unendlich grosse Datenmengen zu transportieren/umzuwandeln.
    Wie gesagt: Das gilt für den gezeigten Code - evtl. fährt da noch annerer Code herum, bei dems anners aussieht.



    Wie dem auch sei, du musst es iwie hinkriegen, den Fehler zu reproduzieren.
    Dass du sagen kannst: "Mit dieser Datei brichts ab".
    Dann kannste jede Menge Code auskommentieren - damit du am Ende sagen kannst: "Mit diesem Code passierts".



    Was mich auch wundert ist, dass scheints keine Fehlermeldung gibt.
    Du hast nicht etwa irgendwo im Code einen TryCatch, der Fehlermeldungen verschluckt?
    Hallo ErfinderdesRades,

    Nein, da ist kein weiterer Code. Den Flush hatte ich getestet und wieder auskommentiert.

    Ich versuche gerade das Ganze mal als WPF zu programmieren und schau, ob es als Programm am eigenen PC auch passiert.

    Hat auch den Vorteil, dass ich zu Hause etwas mehr Zeit habe, das ganze zu testen. Die Webseite geht nur von der Firma aus.

    Ich melde mich dann, wenn ich mehr weiß.
    :!: Leider hab ich nicht immer Zeit zum Programmieren, da es eher ein Hobby ist. Falls ich mal im Forum ne Frage stelle und länger nicht antworte, nicht böse sein: Ich bin dann entweder beruflich oder mit der Familie zu sehr eingespannt oder einfach zu müde. Das kann erfahrungsgemäß auch mal über Wochen dauern, aber ich melde mich immer und setze die Frage ggf. auf beantwortet.
    Hallo,

    ich hab's geschafft! Aber nicht mit CSVhelper, den hab ich
    jetzt rausgeschmissen. Der scheint öfter so Problemchen zu verursachen.

    VB.NET-Quellcode

    1. Dim WorkingFolder = "C:\Users\*\Downloads"
    2. Dim WorkingFile2 = "C:\Users\*\Downloads\lod.csv"
    3. If File.Exists(WorkingFile2) = True Then
    4. File.Delete(WorkingFile2)
    5. End If
    6. Dim xmlfile = Path.Combine(WorkingFolder, "lod-opendata.xml")
    7. Dim str_item As String
    8. Dim str_variantcorrect As String
    9. Dim str_pluriel As String
    10. Dim str_pluriel2 As String
    11. Dim str_pp1 As String
    12. Dim str_pp2 As String
    13. Dim str_pp3 As String
    14. Dim str_pp4 As String
    15. Dim str_pp5 As String
    16. Dim str_pp6 As String
    17. Dim str_ip1 As String
    18. Dim str_ip2 As String
    19. Dim str_ip3 As String
    20. Dim str_ip4 As String
    21. Dim str_ip5 As String
    22. Dim str_ip6 As String
    23. Dim str_ppp1 As String
    24. Dim str_ppp2 As String
    25. Dim str_cpp1 As String
    26. Dim str_cpp2 As String
    27. Dim str_cpp3 As String
    28. Dim str_cpp4 As String
    29. Dim str_cpp5 As String
    30. Dim str_cpp6 As String
    31. Dim str_renv As String
    32. Dim boo_varianteh As Boolean
    33. Dim boo_variantel As Boolean
    34. Dim boo_varianteo As Boolean
    35. Dim boo_p As Boolean
    36. Dim boo_i As Boolean
    37. Dim boo_cp As Boolean
    38. Dim int_len As Integer
    39. Dim readxml As XmlReader = XmlReader.Create(xmlfile)
    40. Using csvwriter As StreamWriter = File.CreateText(WorkingFile2)
    41. csvwriter.WriteLine("wuert,pluriel1,pluriel2,variantcorrect,varianteh,variantel,varianteo,ppp1,ppp2,pp1,pp2,pp3,pp4,pp5,pp6,cpp1,cpp2,cpp3,cpp4,cpp5,cpp6,ip1,ip2,ip3,ip4,ip5,ip6")
    42. End Using
    43. Using readxml
    44. While readxml.Read
    45. If readxml.IsStartElement Then
    46. If readxml.Name = "lod:AUDIO" Then
    47. readxml.Skip()
    48. End If
    49. If readxml.Name = "lod:ITEM-ADRESSE" Then
    50. If readxml.Read() Then
    51. str_item = readxml.Value.Replace("_", " ")
    52. End If
    53. End If
    54. … ('aulesen der xml)
    55. If readxml.NodeType = XmlNodeType.EndElement Then
    56. If readxml.Name = "lod:ITEM" Then
    57. Using csvwriter As StreamWriter = File.AppendText(WorkingFile2)
    58. csvwriter.WriteLine(str_item & "," &
    59. str_pluriel & "," & str_pluriel2 & "," &
    60. str_variantcorrect & "," & boo_varianteh & "," &
    61. boo_variantel & "," & boo_varianteo & "," & str_ppp1
    62. & "," & str_ppp2 & "," & str_pp1 & "," & str_pp2
    63. & "," & str_pp3 & "," & str_pp4 & "," & str_pp5
    64. & "," & str_pp6 & "," & str_cpp1 & "," &
    65. str_cpp2 & "," & str_cpp3 & "," & str_cpp4 & ","
    66. & str_cpp5 & "," & str_cpp6 & "," & str_ip1 &
    67. "," & str_ip2 & "," & str_ip3 & "," & str_ip4 &
    68. "," & str_ip5 & "," & str_ip6)
    69. End Using
    70. boo_varianteh = False
    71. boo_variantel = False
    72. boo_varianteo = False
    73. boo_cp = False
    74. boo_i = False
    75. boo_p = False
    76. str_item = ""
    77. str_variantcorrect = ""
    78. str_pluriel = ""
    79. str_pluriel2 = ""
    80. str_pp1 = ""
    81. str_pp2 = ""
    82. str_pp3 = ""
    83. str_pp4 = ""
    84. str_pp5 = ""
    85. str_pp6 = ""
    86. str_ip1 = ""
    87. str_ip2 = ""
    88. str_ip3 = ""
    89. str_ip4 = ""
    90. str_ip5 = ""
    91. str_ip6 = ""
    92. str_ppp1 = ""
    93. str_ppp2 = ""
    94. str_cpp1 = ""
    95. str_cpp2 = ""
    96. str_cpp3 = ""
    97. str_cpp4 = ""
    98. str_cpp5 = ""
    99. str_cpp6 = ""
    100. End If
    101. End If
    102. End While
    103. End Using


    LG,
    Pascal
    :!: Leider hab ich nicht immer Zeit zum Programmieren, da es eher ein Hobby ist. Falls ich mal im Forum ne Frage stelle und länger nicht antworte, nicht böse sein: Ich bin dann entweder beruflich oder mit der Familie zu sehr eingespannt oder einfach zu müde. Das kann erfahrungsgemäß auch mal über Wochen dauern, aber ich melde mich immer und setze die Frage ggf. auf beantwortet.
    @Translating-IT Die vielen Strings schreien doch danach, als Array implementiert zu werden :!:
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    VB-Fragen über PN / Konversation werden ignoriert!
    Hallo RodFromGermany,

    Ja, bin noch nicht ganz fertig, das Aufräumen kommt später.

    Mein ersten Ziel war mal die CSV-Datei richtig erstellen zu können. Beim Anschauen dieser bin ich dann schon drauf gekommen, dass ein Teil der Daten ergänzt oder gar geschnitten werden muss.

    Ich muss dazu erst mal die gesamte XML zerpflücken und schauen, was ich von den Daten wirklich alles brauche und in welchem Format. Dazu kommt noch, dass ich
    gleichzeitig eine 2. XML-Datei auslesen muss, und Teile der Daten auch in die CSV übertragen muss. Wenn ich das alles fertig habe und weiß, welche Strings (von diesen und noch etliche dazu) benötigt werden, kann ich den Code optimieren.

    Edit: Hab vergessen, dass ein Array hier nicht geht, da die Daten nicht immer in derselben Reihenfolge auftreten und ab und zu muss ich bei einigen Knoten auch Attribute auslesen, die bei anderen nicht vorkommen. Bei der zweiten Datei wäre es einfacher, die hat immer dieselben Inhalte zum Auslesen.
    :!: Leider hab ich nicht immer Zeit zum Programmieren, da es eher ein Hobby ist. Falls ich mal im Forum ne Frage stelle und länger nicht antworte, nicht böse sein: Ich bin dann entweder beruflich oder mit der Familie zu sehr eingespannt oder einfach zu müde. Das kann erfahrungsgemäß auch mal über Wochen dauern, aber ich melde mich immer und setze die Frage ggf. auf beantwortet.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Translating-IT“ ()