einXSLTbeginnerDerSichSchrittFuerSchrittHEranwagt: Schreiben mehrerer CSV-Dateien

Hallo liebe Leutz,

ich habe hier ein Problem mit XSLT, liegt mit hoher Wahrscheinlichkeit auch daran, dass ich noch nicht völlig hinter der Abarbeitung einer XSL-Transformation blicke.

Ich habe ein XML-Dokument mit folgendem Aufbau:

-Root
  -SalesOrder (können mehrere sein)
  -number (z.b. 123)
  -status (z.b. ok)
  .
  .
  .
  -Details (können ebenfalls mehrere sein)
    -Subnumber (z.b. 456)
    -reference (z.b. abc)
    .
    .
    .

Mein Ziel ist, zwei CSV-Dateien zu erzeugen, eine mit dem Inhalt aller Werte von "Details", jeder Wert getrennt durch ein Trennzeichen meiner Wahl (also , oder ; und so), und einer Datei, gefüllt mit den Werten aus "SalesOrder" OHNE die Werte von "Details", ebenfalls durch Trennzeichen getrennt.

Das ganze sollte so aussehen:
_________________
Datei1.csv:

123, ok, ..., ...
_________________
Datei2.csv:

456, abc, ..., ...

Das ganze muss mit "result-document" funktionieren.
Ich habe schon vieles ausprobiert und es auch geschafft, Werte in eine CSV zu schreiben.

Leider scheiterte es immer damit, dass ich die Werte auf einen Schlag geschrieben habe und ich somit kein Trennzeichen zwischen den Werten platzieren konnte (also kein valides csv).
Versuche, die Werte einzeln zu schreiben endeten stets erfolglos mit der exception, das ich nicht mehrfach in eine Datei schreiben kann (Cannot write more than one result doc to the same URI).

Ausserdem klappt mein handling mit den templates auch noch nicht so richtig.

Ich hab vieles probiert und gegoogelt, bin aber jetzt ziemlich ratlos und wende mich an einen XSLT-spezialisten.

Hier einmal mein (gefühlt 100. Umbau) meines XSLTs (das ist eine UNFERTIGE Version,also bitte nicht sagen "wie soll das damit gehen". Mir ist auch bewusst, dass ich zuerst Versuche, nur eine Datei zu erzeugen, weil wenn es noch nichtmal mit einer klappt..):

<xsl:template match="/">  
	<xsl:for-each select="//Details">  
		<xsl:result-document href="Pos.csv" format="csv">  
			<xsl:value-of select="child::\*"/>  
			<xsl:text>, </xsl:text>  
		</xsl:result-document>  
	</xsl:for-each>  
</xsl:template>  

Im großen und ganzen frag ich eigentlich nur, wie schreibe ich Werte nacheinander in eine Datei, und füge zwischen jedem Wert ein eigenes Zeichen ein, und geht das überhaupt?
Wer eine Idee hat, bitte auch kurz beschreiben was denn da passiert, sonst lern ich das nie ^^

Bin natürlich für jede Hilfe dankbar!

  1. Tach!

    Meine XSLT-Versuche liegen nun auch schon wieder eine Weile zurück, und ich werde dir vielleicht nicht wirklich weiterhelfen aber hoffentlich eine grobe Richtung vorgeben können.

    Versuche, die Werte einzeln zu schreiben endeten stets erfolglos mit der exception, das ich nicht mehrfach in eine Datei schreiben kann (Cannot write more than one result doc to the same URI).
    <xsl:template match="/">
      <xsl:for-each select="//Details">
        <xsl:result-document href="Pos.csv" format="csv">
          [...]
        </xsl:result-document>
      </xsl:for-each>
    </xsl:template>

    Kommt die Exception bei dieser Konstruktion, also bei result-document innerhalb von foreach? Dann ist das mit dem result-document vermutlich so ähnlich wie beim Erstellen einer Variable mit variablem Inhalt. Man darf das sinngemäß nicht so tun:
      if (bedingung) then z= x else z= y
    weil dabei das z= zweimal vorkommt. Man muss das andersrum notieren
      z= if (bedingung) then x else y
    also das z= nach außen bringen und den variablen Inhalt nach innen.

    Im großen und ganzen frag ich eigentlich nur, wie schreibe ich Werte nacheinander in eine Datei, und füge zwischen jedem Wert ein eigenes Zeichen ein, und geht das überhaupt?

    Naja, so imperativ, wie du das formulierst, geht das nicht (besonders gut). Du musst die Kontrolle über das Gesamtgeschehen abgeben (beziehungsweise bekommst sie bei XSLT gar nicht erst), und kannst immer nur die Regel definieren, die auf ein bestimmtes Element angewendet werden soll.

    Das Root-Element kann/sollte natürlich auch eine Behandlung erfahren. Da musst du vermutlich nur das result-document notieren und darin ein apply-templates (und vielleicht davor und danach noch mehr, was einmalig am Anfang und am Ende ausgeführt werden soll, wie zum Beispiel eine Feldnamen-Zeile). Für die anderen Elemente erstellst du eigene Templates. Wenn das wieder nur Container-Elemente sind, dann ein weiteres apply-templates darin anwenden.

    Im Prinzip wie bei diesem Beispiel: http://de.selfhtml.org/xml/darstellung/xsltbeispiele.htm#textbeispiel

    Wenn du in deinem XML-Baum soweit ab-(oder auf-)gestiegen bist, dass du nur noch Templates für Blätter schreiben kannst, dann gib jeweils den Inhalt des Blattes aus mit einem Komma danach, außer beim letzten Element (der CSV-Zeile). (Anführungszeichen um die Werte zu notieren und Anführungszeichen in ihnen drin zu verdoppeln wäre auch nicht verkehrt, um den CSV-Regeln in jedem Fall zu entsprechen.)

    dedlfix.

  2. Hallo,

    Wer eine Idee hat, bitte auch kurz beschreiben was denn da passiert, sonst lern ich das nie

    Poste mal ein konkretes, testbares XML-Dokument und das erwartete CSV-Ergebnis.

    Grüße,
    Thomas