Zum Inhalt

CSV-Import

Konzept

Die manuelle Konfiguration für den Import von CSV-Dateien besteht aus einer XML-Konfigurationsdatei für den Implex. Diese Datei ist in mehrere Abschnitte unterteilt, um den Login zur CortexEngine, das Lesen der Quellen (ReaderModule) und das Mapping zwischen Quelle und Ziel sicherzustellen. Der Aufbau dieser Konfigurationsdatei ist grundsätzlich für jeden Import gleich und unterscheidet sich in den jeweiligen Parametern für Quellen, ReaderModule und Ziel-Mapping.

Wichtig

In der ersten Zeile einer CSV-Datei befinden sich Spaltenüberschriften (Feldbezeichner). Ist das nicht der Fall, müssen Sie in der Konfigurationsdatei im Abschnitt ReaderModule der Wert für den SpaltenModus ändern. Hier stehen die Möglichkeiten HEADER (wenn die erste Zeile die Bezeichner enthält), NUMERIC oder ABC zur Verfügung.

ReaderModule für CSV-Dateien

Die CSV-Dateien zeigen zwei zu importierende Datensätze mit den jeweiligen Feldbezeichnern in der ersten Zeile.

Beispiel einer CSV-Datei (mit Semikolon getrennte Werte):

"Name";"Vorname";"Ort";"HobbyNr";"Hobbies" "Meier";"Max";"Hamburg";"1,2";"Fußball,Hockey" "Müller";"Sandra";"Bielefeld";"1,2";"Tanzen,Reiten"

Beispiel einer CSV-Datei (mit Tab getrennte Werte):

"Name" "Vorname" "Ort" "HobbyNr" "Hobbies" "Meier" "Max" "Hamburg" "1,2" "Fußball,Hockey" "Müller" "Sandra" "Bielefeld" "1,2" "Tanzen,Reiten"

Der Abschnitt für den Bereich <ReaderModule...="[...]"> zeigt die dazu passenden Konfigurationseinstellungen für Semikolon-getrennte Werte.

Beispiel CSV-Datei
<ReaderModule type="csv">
    <Filename>/Data/import/2024Mai.csv</Filename>       <!-- relative path to implex in bin directory -->
    <Separator>;</Separator>                            <!-- field separator -->
    <Enclosure>"</Enclosure>                            <!-- field delimiter -->
    <RepSeparator>,</RepSeparator>                      <!-- separator for repeated content in one field; e.g.: "email 1; email 2; email 3; ..." -->
    <ColumnMode>HEADER</ColumnMode>                     <!-- column mode HEADER, NUMERIC, ABC -->
    <Charset>UTF-8</Charset>
</ReaderModule>

Für einen erfolgreichen Import der Datei müssen Sie

  • den Dateinamen mit dem absoluten Pfad angeben
  • den richtigen Zeichensatz (<Charset>) der Importdatei definieren, damit Umlaute und Sonderzeichen korrekt interpretiert werden (UTF-8, Windows-1251 und ISO-8859-1)
  • andere Zeichen als Semikolons zur Trennung der Werte, müssen im Feld FeldTrenner spezifizieren.
  • bei der Verwendung von Tabulatoren den Platzhalter {TAB} verwenden
Beispiel Konfigurationsblock für Tab-getrennte Werte:
<ReaderModule type="csv">
    <Filename>/Data/import/2013Mai.csv</Filename>
    <Separator></Separator>
    <Enclosure>"</Enclosure>
    <RepSeparator>,</RepSeparator>
    <ColumnMode>HEADER</ColumnMode>
    <Charset>UTF-8</Charset>
</ReaderModule>

Werden die bisher gezeigten Beispiele als Konfigurationsdatei zusammengefügt, sieht die XML-Datei so aus:

Beispiel Konfigurationsblock
<xml version="1.0" encoding="UTF-8"?>
<CtxImport>
  <Global>
    <LoginIP>127.0.0.1</LoginIP>
    <LoginPort>29001</LoginPort>
    <LoginUser>admin</LoginUser>
    <LoginPW>adm#13qzy2!</LoginPW>
    <ImportMode>nu</ImportMode>
</Global>
<ReaderModule type="csv">
    <Filename>/Data/import/2024Mai.csv</Filename>
    <Separator>;</Separator>
    <Enclosure>"</Enclosure>
    <RepSeparator>,</RepSeparator>
    <ColumnMode>HEADER</ColumnMode>
    <Charset>UTF-8</Charset>
</ReaderModule>
<ImportSection recordtype="[.......]">
    [.......]
</ImportSection>
</CtxImport>

Import-Sektion für CSV-Dateien

Innerhalb der <ImportSection ...="[...]" legen Sie die Feldzuweisungen und Referenzen für den Import fest. Sie können Feldinhalte als Verlaufsinformation speichern und weitergehende Funktionen nutzen (z.B. Fallunterscheidungen anhand bestimmter Inhalte oder die Änderung von Inhalten definieren).

Zu dem oben aufgeführten CSV-Beispiel kann die nachfolgende Import-Section dienen, wenn Felder mit den Synonymen perName, perVorn und perAOrt vorhanden sind:

Import Section
<ImportSection recordtype="PERS">
    <Reference>perName</Reference>
    <Field>perName=getChar('Name')</Field>
    <Field>perVorn=getChar('Vorname')</Field>
    <Field>perAOrt=getChar('Ort')</Field>
</ImportSection>
  • Als Parameter für die <ImportSection ...="[...]" wird das Kürzel des Datensatztyps festgelegt (in dem gezeigten Beispiel <...> ...="PERS").
  • Die Feldzuweisungen beziehen sich damit auf diese Satzart.
  • Neue Datensätze werden angelegt, wenn anhand der Referenz kein Datensatz für eine Aktualisierung gefunden werden kann und der ImportModus auf nu oder n gesetzt wurde.

Datensätze aktualisieren

Wenn Sie vorhandene Datensätze aktualisieren möchten, ist es notwendig, dass Sie ein Referenzfeld angeben. Dieses legen Sie über den Eintrag Referenz fest.

Alle weiteren Quellfelder weisen Sie dann einem Ziel zu, indem Sie für jede Zuweisung einen Eintrag erstellen. Die Zuweisung besteht dann immer aus Ziel = Quelle.

<Field>perName=getChar('Name')</Field>

Bei diesem Beispiel wird dem Zielfeld perName der Wert aus dem Feld 'Name' zugewiesen. Beachten Sie, dass die Quellfelder in jedem Fall mit der Funktion getChar umschlossen werden.

Import von CSV-Dateien ohne Header

Liegen CSV-Dateien ohne Header vor und wurde im ReaderModule entweder NUMERIC oder ABC angegeben, müssen auch beim Lesen der Felder andere Angaben erfolgen. Die Funktion getChar kann in diesem Fall nicht auf einen Feldnamen, sondern auf die numerischen oder alphabetischen Spaltenangaben, sondern angewendet werden.

Beispiel für numerische Header
<Field>perName=getChar('0')</Field>
<Field>perLNam=getChar('1')</Field>
Beispiel für alphabetische Header
<Field>perName=getChar('A')</Field>
<Field>perLNam=getChar('B')</Field>

Nutzung von Funktionen

Für die Konfiguration stehen Ihnen mehrere Funktionen zur Verfügung mit deren Hilfe Sie die Inhalte ändern können. Eine komplette Übersicht finden Sie im Abschnitt Funktionen.

Beispiele für Konfigurationsfunktionen
<ImportSection recordtype="PERS">
  <Reference>perName</Reference>
  <Field>perName=getChar('Name')</Field>
  <Field>perVorn=getChar('Vorname')</Field>
  <Field>perAOrt=getChar('Ort')</Field>
  <Field>Quelle=file_woext(sourceFileName)()</Field>
  <Field>perGes=iif(getChar('Vorname')== 'Max','M','W')</Field>
  <Field>perSuch=getChar('Vorname')+getChar('Name')</Field>
</ImportSection>

Die Funktionen greifen auf verschiedene Daten zurück und erzeugen neue Informationen:

  • Der Dateiname der an die Funktion file_woext übergeben wird, muss ohne die Dateiendung (extension) angegeben werden (aus 2024Mai.csv wird so 2024Mai).
  • Per iif wird eine Fallunterscheidung anhand des Vornamens durchgeführt: Im Fall von 'Max' erhält das Feld perGes (Geschlecht) den Wert 'M', ansonsten 'W'.
  • Ergänzend dazu werden die Quellfelder 'Vorname' und 'Name' zu einem Wert zusammengefügt und in das Feld 'perSuch' geschrieben.

Hinweis

Beachten Sie bei Rechenoperationen, dass die Quellwerte zuvor als numerische Werte deklariert werden müssen (casting). Dieses führen Sie beispielsweise mit den Funktionen cint oder cfloat durch. Auch für weitere Typen kann es vorkommen, dass Sie eine Anpassung durchführen müssen (z.B. für die Umwandlung von Zahlen in Text).

Wiederholfelder und Wiederholfeldgruppen

In der Feldkonfiguration können Sie definieren, dass ein Feld mehrfach innerhalb eines Datensatzes gespeichert werden soll (z.B. Hobby oder E-Mail-Adresse). Diese Wiederholfelder können als eine Gruppe zusammengefasst werden (z.B. die Bankverbindung mit Konto, BLZ, IBAN,...). Die entsprechenden Daten können Sie daher auch über die Import-Funktion aus einer Quelle in die CortexEngine einlesen.

Die CSV-Dateien beinhalten die Hobbies und eine Nummer der Hobbies, die zusammen eine Wiederholfeldgruppe bilden und entsprechend konfiguriert werden müssen.

Nummer und Bezeichnung der Hobbies sollen nun als Wiederholfeldgruppe in die Satzart der Person importiert werden. Dafür ergänzen Sie die <ImportSection ...="[...]"> um folgende Angaben. Damit werden die erste Nummer und das erste Hobby als eine Gruppe betrachtet, gefolgt von der zweiten Nummer und dem zweiten Hobby, usw.

Beispiel Ergänzung für Wiederholfeldgruppen
<RepGroup>
  <Field>HobNr  = getChar('HobbyNr')</Field>
  <Field>HobBez = getChar('Hobbies')</Field>
</RepGroup>

Wenn es sich um ein einzelnes wiederholtes Feld ohne weitere Gruppierung handelt, wird das einzelne Feld in die Gruppe der wiederholten Felder geschrieben.

Beispiel einzelnes Feld
<RepGroup>
  <Field>HobBez = getChar('Hobbies')</Field>
</RepGroup>

Tipp

Sie können auch mehrere Wiederholfelder und Wiederholfeldgruppen in einem Datensatz aufnehmen.

Hinweis

Eine Gruppe von Feldern kann aktualisiert werden, wenn eine Referenz auf ein führendes Feld vorliegt und die Gruppe, die nicht mehr in der Quelle vorhanden ist, kann gelöscht werden. Hierfür ist eine Erweiterung des oben genannten Beispiels notwendig:

Beispiel Erweiterung für Aktualisierung einer Gruppe von Feldern
<RepGroup reference="1">
  <Field deltalist=" d">HobNr = getChar('HobbyNr')</Field>
  <Field>HobBez = getChar('Hobbies')</Field>
</RepGroup>

Das Attribut reference aktiviert die Referenzierung der Gruppe. Das erste Feld gilt immer als Referenzfeld, um die Gruppe zu aktualisieren.

Das Attribut deltalist legt fest, dass jeder aus der Quelle zu importierende Datensatz in der CortexEngine vorhanden sein muss. In der Quelle nicht vorhandene Datensätze (neu angelegt oder aktualisiert) werden nach dem Import aus der CortexEngine gelöscht.

Vorsicht

Die Kombination aller Attribute kann möglicherweise ungewünschte Änderungen hervorrufen. Ein vorheriger Test ist daher empfehlenswert.

Import - Beispiel

Werden die bisher gezeigten Beispiele als Konfigurationsdatei zusammengefügt, sieht die XML-Datei so aus:

Vollständige Beispielkonfiguration
<?xml version="1.0" encoding="UTF-8"?>
<CtxImport>
  <Global>
    <LoginIP>127.0.0.1</LoginIP>
    <LoginPort>29001</LoginPort>
    <LoginUser>admin</LoginUser>
    <LoginPW>adm#13qzy2!</LoginPW>
    <ImportMode>nu</ImportMode>
  </Global>
  <ReaderModule type="csv">
    <Filename>/Data/import/2013Mai.csv</Filename>
    <Separator>;</Separator>
    <Enclosure>"</Enclosure>
    <RepSeparator>,</RepSeparator>
    <ColumnMode>HEADER</ColumnMode>
    <Charset>UTF-8</Charset>
  </ReaderModule>
  <ImportSection recordtype="PERS">
    <Reference>perName</Reference>
    <Field>perName=getChar('Name')</Field>
    <Field>perVorn=getChar('Vorname')</Field>
    <Field>perAOrt=getChar('Ort')</Field>
    <Field>Quelle=file_woext(sourceFileName)()</Field>
    <Field>perGes=iif(getChar('Vorname')== 'Max','M','W')</Field>
    <Field>perSuch= getChar('Vorname')+getChar('Name')</Field>
    <RepGroup reference='1'>
      <Field>HobNr  = getChar('HobbyNr')</Field>
      <Field>HobBez = getChar('Hobbies')</Field>
    </RepGroup>
  </ImportSection>
</CtxImport>