XPath 3.0, XPath 2.0, XPath 1.0 / XPath-Funktionen / XPath: Sequenz-Funktionen / XPath: unparsed-text-lines

XPath: unparsed-text-lines

XPath: unparsed-text-lines

➪ Eine häufige Aufgabe ist die Konvertierung CSV nach XML. In XSLT 3.0 gestaltet sie sich noch einfacher als in XSLT 2.0.

Auf dieser Seite:

unparsed-text-lines: CSV in XML konvertieren

beschreibt die Verarbeitung von CSV nach XML in XSL 2.0. In XSL 3.0 steht zusätzlich die Funktion unparsed-text-lines zur Verfügung.

Ich starte 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 -Funktion unter Zuhilfenahme des Trennzeichens (hier: ;) in ein Array überführt. Dabei gehe ich davon aus, dass die Feldnamen in der CSV-Datei weder ein Leer- noch sonst ein Zeichen beinhalten, das später in XML schwierig werden könnte.


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

Anstelle einer detaillierten Funktion verwende ich auch hier eine Variable mit einem 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 mithilfe der Funktionsvariablen $f_erstezeile in sein jeweiliges Start- und Ende-Tag 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 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 / 15. September 2018



Fragen? Anmerkungen? Tipps?

Bitte nehmen Sie Kontakt zu mir auf.






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/unparsedtext_lines.html