XPath 3.0, XPath 2.0, XPath 1.0 / XPath Funktionen / XPath: Sequence-Funktionen / unparsed-text-lines: CSV in XML konvertieren

unparsed-text-lines: CSV in XML konvertieren

unparsed-text-lines: CSV in XML konvertieren

➪ XSLT 3.0 und XPath 3.0 bieten zahlreiche neue Features, z.B. json-to-xml, unparsed-text-lines, xsl:try xsl:catch, xsl:assert, xsl:evaluate, xsl:variable mit anonymem Funktionsaufruf, xsl:iterate.

Die Konvertierung von Nicht-XML-Dateien wie CSV ist unter XSLT 3.0 noch einfacher als unter XSLT 2.0. Starten wir mit Variablen für die CSV-Datei und das darin verwendete Trennzeichen.


<xsl:variable name="csvdatei" select="'Mensch.csv'"/>
<xsl:variable name="trennzeichen" select="';'"/>

Die Variable "erstezeile" ist notwendig für die späteren Elementnamen pro Feld. Wie der Name schon sagt, wird die erste Zeile der CSV-Datei ausgelesen und durch die tokenize-Funktion unter Zuhilfenahme des Trennzeichens (hier: ";") in ein Array überführt. Dabei gehe ich davon aus, daß die Feldnamen in der CSV-Datei weder ein Leer- noch sonst ein Zeichen beinhalten, die später in XML schwierig werden könnten.


<xsl:variable 
     name="erstezeile" 
     select="tokenize(
              unparsed-text-lines($csvdatei)[1], 
              $trennzeichen
             )"/> 

Anstelle einer detaillierten Funktion verwenden wir auch hier wieder eine Variable mit einam anonymen Funktionsaufruf, der ein Integerparameter übergeben wird und die einen String zurückgibt. Diese Funktionsvariable verwendet die vorher beschriebene Variable "erstezeile", um die einzelnen Feldnamen zu ermitteln.


<xsl:variable 
     name="f_erstezeile" 
     select="function($spalte as xs:integer) as xs:string
             {
                 $erstezeile[$spalte]
             }"/>

Der tatsächliche Aufruf erfolgt durch eine Schleife über sämtliche Zeilen, beginnend mit der zweiten Zeile der CSV-Datei (die erste Zeile ist bekanntlich die Headerzeile). Für jede dieser Zeilen habe ich ein XML-Element "DS" für "DatenSatz" definiert. Anschließend wird jedes Feld der jeweiligen Zeile durch die "tokenize"-Funktion ausgelesen und mit Hilfe der Funktionsvariablen "$f_erstezeile" in sein jeweiliges Start- und Endetag gepackt.


<xsl:template name="csvdemo">
  <xsl:element name="ERG">
    <xsl:for-each 
         select="unparsed-text-lines($csvdatei)[position() &gt; 1]">
      <xsl:element name="DS">
        <xsl:for-each 
             select="tokenize(., $trennzeichen)">
          <xsl:variable 
               name="pos" 
               select="position()"/>                         
          <xsl:element 
               name="{$f_erstezeile($pos)}">
             <xsl:value-of select="."/>
          </xsl:element>
        </xsl:for-each>
      </xsl:element>
    </xsl:for-each>
  </xsl:element>
</xsl:template>

Obwohl das Ergebnis natürlich umfangreicher ist, soll die erste Zeile ausreichen:


<ERG>
  <DS>
    <ORTID>1</ORTID>
    <ORTNAME>Neustadt</ORTNAME>
    <ID>1</ID>
    <NAME>Holzflos</NAME>
    <VORNAME>Hugo</VORNAME>
    <GEHALT>234.56</GEHALT>
    <IDORT>1</IDORT>
    <AUSGABEN>3563.1400000000003</AUSGABEN>
  </DS>
</ERG>

wg / 22. März 2018



Fragen? Anmerkungen? Tips?

Bitte nehmen Sie Kontakt zu mir auf:

Vorname
Nachname
Mailadresse





JSON



Vielen Dank für Ihr Interesse an meiner Arbeit.


V.i.S.d.P.: Wilfried Grupe * Klus 6 * 37643 Negenborn

☎ 0151. 750 360 61 * eMail: info10@wilfried-grupe.de

www.wilfried-grupe.de/XSL305.html