Tutorials zum CSV oder XML parsen?

So, endlich mal wieder ne Newbie-Frage :-). Ich möchte eine CSV oder XML-File von einer SD-Karte lesen und dann parsen. Hat jemand ein paar gute Tutorials parat? Gegoogelt komme ich irgendwie immer nur auf halbe oder Teillösungen, die dann auch noch nur halbherzig erklärt werden oder schon so einiges voraussetzen. Bevor ich mich da durchwurschtel wäre es cool, mal ein richtiges Tutorial zu lesen, so es sowas gibt.

Was ich machen möchte sieht in XML in etwas wie folgt aus:

<setlist>
 <song name="">
 <part name="" description="" midicommand=""></part>
 </song>
</setlist> 


// Beispiel
<setlist>
 <song name="The Lovesong">
 <part name="Intro" sounddescription="Clean mit Delay" midicommand="xxx"></part>
 <part name="Strophe I" sounddescription="Clean mit Chorus" midicommand="xxx"></part>
 <part name="Bridge" sounddescription="Light Crunch" midicommand="xxx"></part>
 ...
 </song>
 <song name="The Rocksong">
 <part name="Intro" sounddescription="Clean mit Delay" midicommand="xxx"></part>
 ...
 </song>
 <song name="The Progsong">
 <part name="Intro" sounddescription="Clean mit Delay" midicommand="xxx"></part>
 ...
 </song> 
</setlist>

Ich möchte nun mit zwei Knöpfen zwischen den -Elementen hin und her springen können und mit zwei weiteren Knöpfen innerhalb des jeweils aktiven -Element zwischen den -Elementen wechseln und die jeweiligen Attribute in Variablen schrieben und ausgeben.

Für konkrete Lösungsvorschläge (mit ausführlicher Erklärung) wäre ich natürlich auch dankbar. :slight_smile:
CSV/

wie viele (Kilo)byte wird das xml haben und auf welchem Controller bist du?

Ein DOM Parser für XML ist wahrlich kein Anfängerprojekt, dafür braucht man etliche Kenntnisse, ohne die man die Anleitungen kaum verstehen kann.

Wie wär's mit CSV statt XML, das geht viel einfacher und platzsparender?

noiasca:
wie viele (Kilo)byte wird das xml haben und auf welchem Controller bist du?

Bin auf nem Arduino Uno unterwegs. Denke mal, dass die Struktur, wenn ich sie in XML abbilden würde so zwischen 20 und 30 kb groß werden könnte.

DrDiettrich:
Ein DOM Parser für XML ist wahrlich kein Anfängerprojekt, dafür braucht man etliche Kenntnisse, ohne die man die Anleitungen kaum verstehen kann.

Wie wär's mit CSV statt XML, das geht viel einfacher und platzsparender?

Hätte jetzt gehofft, dass es dafür schon Librarys gibt, mit denen das ohne zu komplex zu werden handeln kann.

Mein Problem ist, dass die einzelnen Song unterschdielich viele Parts haben können. Habe da so auf Anhieb nicht die Idee, wie man das mit CSV lösen kann. Außerdem sollte die einzulesende Datei nicht zu komplex sein, da ich die erst mal per Hand füllen werde.

Aber wenn es ein paar gute Tutorials oder gut kommentierte Beispiele für CSV gibt wäre das natürlich auch ein schöner Schritt in die richtige Richtung.

Passt nicht ganz her rein. Habe mich letzten 2 Wochen viel mit Json beschäftigt und auch die ArduinoJSON v6 genutzt bei der Analyse von Openweathermap Daten war es schon so das auf deinem ESP8266 bei einem JSON mit ca 20kB es maximal 1 Tag zuverlässig lief danach hat es einen neustart versucht da der Buffer Statisch(genutz weil kleiner) war und Dynmisch maximal 2h. Deswegen denke ich das es mit nem kleinen Arduino und 20k XML es nicht zuverlässig läuft. Ich habe einen Arudino Stream Json Parser gefunden der halbwegs läuft.
Wenn du selber die daten Datei erstellst ist evtl JSON der einfachere weg da es dort schon mehr gibt. Ob das aber mit deinem Umfang passt kann ich dir leider nicht sagen.

Falls du dich für JSON entscheidest hier der Link GitHub - squix78/json-streaming-parser: Arduino library for parsing potentially huge json streams on devices with scarce memory

Gruß
DerDani

wenn ich sie in XML abbilden würde so zwischen 20 und 30 kb groß werden könnte.

Dass der Uno insgesamt 2 kB RAM hat, ist dir sicherlich bewusst. Und die Hälfte davon braucht die SD Bibliothek, um überhaupt auf eine Datei zugreifen zu können.
Eine allgemein verwendbare Bibliothek ist da sicher nicht machbar/brauchbar.

Sind alle Elemente in einer setlist oder wird es mehrere setlist Elemente geben?
Wie viele Elemente erwartest du?
Wie viele hat der größte Song?
Wie viele über alle songs gibt es voraussichtlich?
Wie viele Byte hat das größte midicommand?
Wie viel RAM und Flash hast du am jetzigen Sketch noch frei?

(inhaltlich bin ich bei michael_x … du musst dir da wohl was passendes zurechtschnitzen wenn das am Uno was werden soll).

Ja, dass man das xml nicht komplett in den Speicher eines Arduino bekommt habe ich schon schwer vermutet.

Um den Speicher zu minimieren hatte ich mir gedacht, jedweils nur die des aktiven zu laden. Ich schätze mal, dass es nicht mehr als 6 bis 7 pro Song geben wird, i.d.R. vermutlich eher weniger. Die Midi-Commands sollten jeweils 2 bis 3 byte (je nach dem, ob ich einen program-chande oder einen controlchange mache… hängt etwas von den verwendtetn Sounds des anzusteuerenden Effektgerätes ab).

Wir ein Song gewechselt könnte man noch mal neu auf die SD-Karte zugreifen und alle in ein Array laden, über die mann dann nach Auswahl die richtigen lädt.

Das ich mir was selber zusammenbauen muss hatte ich ja schon vermutet. Deshalb ja auch die Frage nach brauchbaren Tutorials. Ist halt mit themenspezifischen Schnipseln via google schwierig, sich da sinvoll einzuarbeiten.

Mit jason habe ich leider noch weniger Ahnung. Da müßte ich dann komplett von 0 anfangen. Meine aktive Programmierzeit ist leider schon locker 15 bis 20 Jahre her :-).

in5y372:
Um den Speicher zu minimieren hatte ich mir gedacht, jedweils nur die des aktiven zu laden.

Das wäre bei CSV die Zeile, in der der Titel oder wasauchimmer des aktiven Songs steht. Die Einzelheiten dazu stehen dann in den mit Kommas getrennten Teilen dieser Zeile. Viel einfacher kann man sich das Parsen nicht machen.

Am Uno würde ich das in einer Statemachine machen.
Schrittweise durchgehen und nur in den RAM holen was benötigt wird.
Übernahme in ein Struct-Array
Leerschritte und Zeilenschaltungen zwischen den einzelnen Schritten überlesen
(oder eben nicht in die Variablen übernehmen).

Dazu

eine Funktion die einen Suchbegriff/needle übernimmt
und das struct-array befüllt.
Und als Ergebnis
0 nok
1 gefunden zurückgibt (vieleicht Anzahl der gefundenenen parts des Songs)

grob gesagt

'suchen
lesen bis <setlist>
lesen bis <song name="needle">
while not </song>
  while not </part>
    'part einlesen und in ein struct array übernehmen
    jeweils ab <part name=" einlesen, und beim nächsten " wieder aufhören
    ebenso midicommand="  abwarten, dann einlesen bis zum nächsten "
    nächster index im Array

vieleicht auch noch den Vorgänger und Nachfolger songname aus dem File merken (oder zwei Funktionen: Finde Vorgänger, Finde Nachfolger) damit man so etwas wie eine scrollbare “Liste” auf dem Display simulieren kann und so indirekt auch den nächsten Suchbegriff hat.

Klingt schlecht? Gut, dann Finger weg :wink:
denn immer daran denken, nur:
Chuck Norris can parse HTML with regex.

Das alles will man sich auf einem 328 nicht antun, wenn der RAM schon von SD belegt ist.
Dafür wäre dann mindestens ein ESP sinnvoll oder in meinen Augen ein Raspi, wenn man etwas Komfort haben will. Da gibt es auch Code für XML-Parser.

Gruß Tommy

@noiasca: Das perfekte Beispiel für Posts, die ich auf meiner Suche zu Hauf gefunden habe :slight_smile: . Ist für einen Nicht-Informatier leider nur bedingt verständlich. Statemachine? Struct-Array? Needle? nok? Das ist leider für jemanden, der sich in das Thema einarbeiten will ohne genauere Erklärung oder längerer Recherche nicht so ganz nachvollziehbar. Deshalb ja auch meine eigentliche Frage nach guten Tutorials :-). Generell klingt das von dir vorgeschlagene Vorgehen soweit ich es verstanden habe prima. Nur wie ich es konkret Umsetze... keine Ahnung, da ich für sowas keine brauchbaren Vorlagen/Tutorials/Erklärungen finde.

@Tommy56: Was genau ist ESP? Ein Raspi hatte ich auch schon mal überlegt, aber die brauchen immer so lange zum booten. Außerdem müßte ich mich dann in noch ein System einarbeiten :-).

Wäre ein Teensy 3.2 eine Überlegung wert? Der ist mit 256 K Flash und 64 K RAM ja deutlich besser ausgestattet.

Um mal die Idee mit einer CSV-Liste aufzugreifen. In der Theorie könnte man es doch so machen, dass in der ersten Zeile die ganzen Songs aufgelistet werden. Das würde ich in ein Array schreiben. Mit den Song-Auswahl-Knöpfen würde ich dann das entsprechende Element anspringen und danach die richtige Zeile von der SD-Karte laden und in ein weitere Array laden. Dort würde ich dann drei Arrays mit den Parametern Part, SoundName und Midi-Commando füllen. Mit den Part-Knöpfen würde ich dann die entsprechenden Elemente anspringen. Eine CSV könnte dann in etwa wie folgt aussehen:

songliste,song1, song2, song3, song4
song1parts,Part1,SoundName,Midi-Commando,Part2,SoundName,Midi-Commando,Part2,SoundName,Midi-Commando
song2parts,Part1,SoundName,Midi-Commando,Part2,SoundName,Midi-Commando,Part2,SoundName,Midi-Commando
song3parts,Part1,SoundName,Midi-Commando,Part2,SoundName,Midi-Commando,Part2,SoundName,Midi-Commando
song4parts,Part1,SoundName,Midi-Commando,Part2,SoundName,Midi-Commando,Part2,SoundName,Midi-Commando

Wenn jemand hier Lust hat, dafür mal den entsprechenden Code zu schrieben und vor allem gut zu dokumentieren wäre das grandios. Wobei es mir sehr auf die Doku ankommt. Ich will ja verstehen, was da warum passiert. Sonst lerne ich nichts :slight_smile:

in5y372:
Ist für einen Nicht-Informatier leider nur bedingt verständlich. ...

Als Nicht-Informatiker kann ich Dir versichern, daß sein Vorschlag gut und zielgerichtet ist. Alles das mußt Du lernen, sonst wird das nichts. Sorry, ist so, aber es ist machbar, aber nicht mal so eben.

in5y372:
@Tommy56: Was genau ist ESP?

ESP8266 oder ESP32 sind vergleichbar mit einem Teensy, nur können die auch noch WLAN und sowas bedienen. Wenn Du mit dem Smartphone die Liste durchgehen wolltest, wärest Du richtig. Auch die ESP können mit der IDE programmiert werden.

in5y372:
Wäre ein Teensy 3.2 eine Überlegung wert?

Auf jeden Fall (ich habe einen Teensy 3.2 für LED-Animationen), wenn Du den Funk nicht benötigst. Teensy 3.5 und 3.6 haben SD gleich mit dabei.

Welche Hardware für Dich geeignet ist, entscheidet auch die weitere Verwendung, denn Du willst ja wahrscheinlich nicht nur eine Liste betrachten.

Ich fände es hilfreich, wenn Du eine XML-Datei als Beispiel anhängen würdest, um mögliche weitere Fallstricke erkennen zu können.

Ich will ja gerne lernen. Deshalb ja auch die wiederholte Frage nach verständlichen Tutorials ;-).

Ich hänge einfach mal ne XMS und ne CSV inline als Beispiel dran, wie ich mir das vorstellen kann. Die sind NICHT in Stein gemeißelt, wenn da irgend was anders sein muss oder etwas umgestellt werden muss, damit es funktioniert oder besser geht… immer gerne. Wie gesagt, mir fehlt da das Wissen.

Und wie gesagt, es muss nicht xml sein. Wenn CSV die einfachere (und für mich eher zu verstehende) Methode ist nehme ich gerne CSV, auch wenn es nicht ganz so schön übersichtlich ist.

Die Dateiendung “txt” kann aus den Dateien rausgenommen werden. Bekomme die ohne nicht angehängt.

setlist-bsp.xml.txt (2.05 KB)

setlist.csv.txt (696 Bytes)

Wenn Dir bisher noch keiner Tutorials zum Parsen von XML auf Arduino gezeigt/verlinkt hat, kannst Du davon ausgehen, dass es keine gibt. Der wahrscheinlichste Grund dafür ist: Das tut sich auf den kleinen MC keiner an. Das haben wir Dir ja schon geschrieben.

Du musst den Raspi ja nicht laufend runter fahren, dann sparst Du die Bootzeit :wink: und nebenbei kann er auch noch anderes erledigen, z.B. Druckerserver, NTP-Server, ...

Um längeres Lernen wirst Du aber auf alle Fälle nicht rum kommen. So einen Parser schreibt man nunmal nicht zwischen Frühstück und Mittagessen.

Gruß Tommy

Hm, sollte ich für sowas vielleicht eher mal unter C nachschauen? Ist das übertragbar?

Das Gerät wird leider regelmäßig transportiert werden (und somit vom Strom getrennt). Aber wenn der Speicher nicht reichen sollte schaue ich mir den Teensy mal genauer an.

Wenn's was größeres sein soll, dann gleich eine Datenbank die man direkt abfragen kann, und keine Parser für irgendwelche schwer beherrschbaren Dateiformate.

Hm, sollte ich für sowas vielleicht eher mal unter C nachschauen? Ist das übertragbar?

Sowohl für C, als auch für C++ gibt es DOM Parser und XML Generatoren.

Alle diese sind für µC eher nicht geeignet, bzw. gar nicht lauffähig.
(aber das wurde dir jetzt ja schon mehrfach gesagt, nur noch nicht von allen)

Grundsätzlich gibt es nichts gegen XML einzuwenden.
Bei geschickter Struktur, der Geschichte, kann man aus den XML automatisch spezialisierte CSV Dateien generieren.

Wobei, wenn sowieso eine SD Karte im Spiel ist, dann ist eine feste Datensatzgröße, mit festen Feldlängen, eigentlich das Mittel der Wahl.
(würde ich mal sagen)
Denn nichts anderes, ist einfacher einzulesen und zu indizieren(mit einem Index zu versehen).

Was im Grunde auch diesem Vorschlag entspricht:

Wenn's was größeres sein soll, dann gleich eine Datenbank die man direkt abfragen kann, und keine Parser für irgendwelche schwer beherrschbaren Dateiformate.

combie:
Bei geschickter Struktur, der Geschichte, kann man aus den XML automatisch spezialisierte CSV Dateien generieren.

Wenn das geht, dann ist XML aber absolut mit Kanonen auf Spatzen geschossen!

Der Vorteil von XML ist ja die Flexibilität, man muß sich an keine einmal festgelegte Struktur halten. Und das ist auch der Grund, warum XML Parser so kompliziert sind. Wer diese Flexibilität nicht braucht, sollte sich diesen Aufwand mit XML auch nicht antun.