Announcement

Collapse
No announcement yet.

per XSLT batch mit Sonderzeichen erzeugen

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • per XSLT batch mit Sonderzeichen erzeugen

    Hallo zusammen,

    ich kämpfe seit einigen Stunden mit einem Encoding-Problem und weiß mir nicht mehr zu helfen. Vielleicht kann mir hier jemand Tipps geben.
    Es geht um folgendes: Aus einem System werden jede Menge Dateien ausgespielt mit Dateinamenschema: RZU_10000000001.pdf bis RZU_n+1.pdf
    Zu diesen vielen Dateien gibt es ein zugehöriges Verzeichnis (XML-Dokument), welche weitere Informationen zu den einzelnen Dateien enthält.
    Da niemand etwas mit den kryptischen Dateibezeichnungen anfangen kann, wollte ich per XSLT eine Batch-Datei erzeugen, die aus den Informationen des Verzeichnisses, bessere Dateinamen erzeugt. Das klappte bisher auch ganz gut, bis in den Informationen Sonderzeichen auftraten, die dann im Batch nicht funktionierten.
    Im Moment interessieren mich erstmal nur die deutschen Umlaute.
    Das Hauptproblem liegt da darin, dass die Batch-Datei ASCII-codiert sein muss und die Umlaute daher etwas anders codiert sind (zum Anschauen: echo äöüÄÖÜ > umlaute.txt). Diese Codierungen habe ich in einer translate-Funktion integriert.

    Hier der XSLT-Codeschnipsel:
    Code:
    <xsl:template match="/">
    	<xsl:text>@echo off</xsl:text>
    	<xsl:value-of select="$newLine"/>
    	<xsl:for-each select="supplierlist/supplier">
    		<!-- alter Dateiname: RZU_... -->
    		<xsl:variable name="oldFilename"><xsl:value-of select="RZU"/></xsl:variable>
    		<!-- neuer Dateiname: Hersteller_-_PDF-Titel_-_MatNr -->
    		<xsl:variable name="newFilename"><xsl:value-of select="translate(PartDenominator,'\/:*?&quot;&lt;&gt;|äöüÄÖÜßÁÀÂáàâÉÈÊéèêÍÌÎíìîÓÒÔóòôÚÙÛúùû°&#xC7;&#xE7;&#xa;’`´ ,','_________„”Ž™šáAAAaaaEEEeeeIIIiiiOOOoooUUUuuu_Cc_____.')"/>_-_<xsl:value-of select="translate(PartTitle,'\/:*?&quot;&lt;&gt;|äöüÄÖÜßÁÀÂáàâÉÈÊéèêÍÌÎíìîÓÒÔóòôÚÙÛúùû°&#xC7;&#xE7;&#xa;’`´ ,','_________„”Ž™šáAAAaaaEEEeeeIIIiiiOOOoooUUUuuu_Cc_____.')"/>_-_<xsl:value-of select="MatNr"/>.pdf</xsl:variable>
    		<!-- Erzeuge Umbenennen-Befehl -->
    		<xsl:text>copy "in\</xsl:text>
    		<xsl:value-of select="$oldFilename"/>
    		<xsl:text>" "out\</xsl:text>
    		<xsl:value-of select="$newFilename"/>
    		<xsl:text>"</xsl:text>
    		<xsl:value-of select="$newLine"/>
    	</xsl:for-each>
    </xsl:template>
    Gebe ich per <xslutput> kein encoding an, bekomme ich genau den Output den ich eigentlich möchte, jedoch in U8-DOS. Das funktioniert auf der Batch nicht, bzw. stimmt da die Codierung nicht.
    Gebe ich per <xslutput encoding="ASCII"/> an, bekomme ich ein ASCII-Dokument, jedoch sind auf einem mal meine Umlaute nicht mit den Zeichen ersetzt, sondern mit Escape-Sequenzen ala ü
    Ok, disable-output-escaping="yes" aktiviert, zeigt aber keine Wirkung. gleicher Output.
    Was nun? Für Tipps und Ideen bin ich dankbar.

    Gruß,
    Johannes

    PS: Wie man an der langen translate-Funktion sieht, habe ich früher einfach alle Sonderformen eines Buchstabens in die Grundform zurückgewandelt, also bspw. ö,ó,ò,ô zu o. Das funktioniert problemlos. Aber aus rein ästhetischen Gründen würde ich nun gerne so viel wie möglich Sonderzeichen erhalten. Wenns einen Weg gibt und der funktioniert, wäre toll, wenn nicht, dann bleibts eben wie bisher.

  • #2
    Die ASCII-Kodierung dürfte streng genommen nur für die Zeichen 0-127 gelten und der XSLT-Prozessor schreibt die darüber liegenden als numerische Zeichenreferenzen raus. Probiere es für DOS/Windows mal mit Windows-1252.

    Hiermit funktioniert das:
    Code:
    <xsl:template match="/">
     <xsl:variable name="str" select="'õ÷³─Í▄'"/>
     <root><xsl:value-of select="translate($str,'õ÷³─Í▄','äöüÄÖÜ')"/></root>  
    </xsl:template>
    Ergebnis:
    Code:
    <?xml version="1.0" encoding="Windows-1252"?>
    <root>äöüÄÖÜ</root>
    Zuletzt editiert von Thomas Meinike; 03.04.2009, 19:57.

    Comment


    • #3
      Hallo Thomas,

      Die ASCII-Kodierung dürfte streng genommen nur für die Zeichen 0-127 gelten und der XSLT-Prozessor schreibt die darüber liegenden als numerische Zeichenreferenzen raus.
      Ja genau, dessen bin ich mir auch bewusst. Saxon z.B. verweigert das XSLT sogar weil er sagt, diese Zeichen gibt es nicht für die gewünschte Codierung.
      Nur frage ich mich, wie kriegt dann DOS/Windows diese Zeichen darein? Wenn ich im Win Notepad das erzeugte Batch-file korrigiere (statt ä, „) dann funktioniert es. Warum aber kann Notepad das Zeichen einfügen, der XSLT-Prozessor aber nicht?
      Andere Alternative ist über cmd.exe und edit.exe. Da kann ich im guten alten Editor sogar direkt äöü schreiben und er codiert es richtig.

      Probiere es für DOS/Windows mal mit Windows-1252
      Damit hatte ich (leider) keinen Erfolg. Aber ich glaube, du hast mich da auch etwas missverstanden. Meine XML-Daten sind ja nicht das Problem, sondern nur das encoding des erzeugten Batch-Files.

      Lasse ich per XSLT das Batch erzeugen in UTF-8 Codierung, dann steht da genau das drin, was ich eigentlich haben will. Nur funktioniert es in der Konsole nicht. Konvertiere ich dann das UTF-8 Batch einfach nach DOS (im Editor), läufts.
      Aber sage ich im XSLT, dass das encoding des zu erzeugendes Batch-Files ASCII sein soll, dann streikt Saxon, xml starlet fügt numerische Sequenzen ein.

      Also, theoretisch würde mir auch ne Funktion reichen, die automatisch das erzeugte UTF-8-Batch ohne zu verändern als encoding DOS bzw. ASCII abspeichert.

      Ich füg mal ein paar Dateien zum Nachvollziehen und probieren ein:
      templist.xml - Das ist das Verzeichnis mit den orignalen Dateinamen und den Zusatzinformationen
      rename_pdfs.xsl - Das ist das XSLT, das das Batch-File zum Umbennen erzeugt.
      rename_pdfs_utf8.bat - Das ist das Batch-File, das bei den momentanen Einstellungen des XSLT rauskommt. Steht alles so drin wie ich es haben will, funktioniert aber auf Grund UTF-8 in der Konsole nicht.
      rename_pdfs.bat - Gleicher Inhalt wie die UTF-8 Version. Aber einfach im Editor (ohne was zu ändern) als _NICHT_UTF8 abgespeichert. --> Funktioniert prima.
      Attached Files

      Comment


      • #4
        Es kommt beim Prozessieren die Meldung, dass ungültige Zeichen 0x81 im XSLT stehen. Im Hex-Editor ist die Stelle zweifach jeweils vor Ž™ zu finden (in der Codeansicht nicht sichtbar, aber an der Stelle lässt sich die rechte Pfeiltaste 2x drücken und erst danach springt der Cursor weiter, da ist also noch etwas ;-). Nach dem Entfernen kann ich ohne Fehlermeldung transformieren. Vielleicht lag es daran. Das Batch-Ergebnis kann ich ja schlecht ausprobieren.

        Comment


        • #5
          Moin Thomas,
          Im Hex-Editor ist die Stelle zweifach jeweils vor Ž™ zu finden (in der Codeansicht nicht sichtbar, aber an der Stelle lässt sich die rechte Pfeiltaste 2x drücken und erst danach springt der Cursor weiter, da ist also noch etwas ;-).
          Das ist leider das kleine ü. Die 6 Zeichen äöüÄÖÜ habe ich aus "echo äöüÄÖÜ > umlaute.txt" rauskopiert.
          Wird bei mir im Editor als Viereck () angezeigt.

          Das Batch-Ergebnis kann ich ja schlecht ausprobieren.
          Schon klar. War nur zu Anschauungszwecken gedacht, um im Editor den Inhalt und das Encoding zu vergleichen.

          Ich hab gestern mal noch kräftig das Netz durchforstet, bin dabei auf cmd /u /c gestoßen. Leider erzeugt das nur ne cmd mit Unicode-Ausgabe. Input UTF-8 nimmts nicht an. :-/

          Comment


          • #6
            Problem gelöst.

            Ich habe nun eine funktionierende Lösung.

            Im XSLT für die zu erzeugende Datei (.bat) das encoding auf ISO-8859-1 stellen.
            Code:
            <xsl:output encoding="ISO-8859-1" />
            und dann als zweiten Befehl für die .bat (nach @echo off) die Codepage ändern.
            Code:
            <xsl:template match="/">
            	<!--**Steps:-->
            	<!--@ Befehlsausgabe ausschalten -->
            	<xsl:text>@echo off</xsl:text>
            	<xsl:value-of select="$newLine"/>
            	<!--@ Codepage ändern -->
            	<xsl:text>chcp 1252</xsl:text>
            	<xsl:value-of select="$newLine"/>
            	<!--@ Für jeden Eintrag -->
            	<xsl:for-each select="supplierlist/supplier">
            		<!--@ Lies alten Dateinnamen aus -->
            ....
            Das Ersetzen (durch Kryptische Zeichen) von äöüÄÖÜß und vielen weiteren Sonderzeichen kann man sich dann damit sparen.
            Es müssen nur noch Zeichen ersetzt werden, die nicht in Dateinamen vorkommen dürfen:
            Code:
            \/:?*"<>|
            und Zeilenumbruch.
            Mein translate hat sich damit auf 10 Zeichen verkürzt:
            Code:
            <xsl:value-of select="translate(PartDenominator,'\/:*?&quot;&lt;&gt;|&#xa;','__________')"/>
            @Thomas
            Vielen Dank für die Tipps und Hinweise. Mit Windows-1252 warst du dicht dran. Das Entscheidende ist die Umschaltung der Codepage in der Batch von ASCII auf 1252.
            Zuletzt editiert von Johannes Meyknecht; 04.04.2009, 13:28. Reason: Erweiterung

            Comment


            • #7
              Hallo Johannes,
              na dann ist es ja gut. Ich wollte gerade die Nutzung der Windows PowerShell statt cmd vorschlagen (wird gerade als optionales Update unter XP und Vista angeboten). Kann vielleicht später mal nützlich sein.
              Grüße, Thomas

              Comment

              Working...
              X