Announcement

Collapse
No announcement yet.

xslt / Regex / *.text to *.text

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

  • xslt / Regex / *.text to *.text

    Hallo zusammen

    Als Vorstufe zur weiteren Verarbeitung per xslt/Sax/batch, muss/möchte ich ein Textdokument in Teile zerlegen.

    Bsp. Mustervorgabe ein Kompendium mit Büchern | Kompendium mit Gedichten.

    BUCHTITEL
    Zeileninhalt
    Zeileninhalt
    Zeileninhalt
    Zeilen- Anzahl je nach Ausgabe varierend
    KAPITEL
    Zeileninhalt
    Zeileninhalt
    Zeileninhalt
    Zeilen- Anzahl je nach Ausgabe varierend
    KAPITEL
    Zeileninhalt
    Zeileninhalt
    Zeileninhalt
    Zeilen- Anzahl je nach Ausgabe varierend
    etc.

    oder

    KOMPENDIUM
    Zeileninhalt
    Zeileninhalt
    Zeileninhalt
    Zeilen- Anzahl je nach Ausgabe varierend
    GEDICHT
    Zeileninhalt
    Zeileninhalt
    Zeileninhalt
    Zeilen- Anzahl je nach Ausgabe varierend
    GEDICHT
    Zeileninhalt
    Zeileninhalt
    Zeileninhalt
    Zeilen- Anzahl je nach Ausgabe varierend
    GEDICHT
    etc.

    Wenn nun ein Buch bsp. 12 KAPITEL hat, bin ich bsp. nur am 5. Kapitel interessiert. (following::*[5])

    Kapitel 1 - 4 und Kapitel 6 - 12, müssten dann im output ausgeschlossen sein.

    Zeileninhalte (bsp. Kapitel 5) müssen für die weitere Verarbeitung erhalten bleiben.

    Ansätze: Regex/xslt input *.txt, output_01 *.txt
    - fn:tokenize($text,'(\r\n)'), ist mir bekannt.


    Für Anregungen vorab vielen Dank.

    Karl_Heg










  • #2
    Hat der Text außer Zeilen irgendeine Struktur? Ist "KAPITEL" als einziges Wort in einer Zeile eine Textmarkierung, nach der man suchen kann? Oder ist das nur ein Beispielwort und im Eingabedokument stehen irgendwelche Kapitelnamen oder Titel?

    Comment


    • #3
      Mit XSLT 3 (vorhanden durch Saxon 9.8 oder neuer) oder Saxon-JS 2 oder Altova XML:

      Code:
      <?xml version="1.0" encoding="UTF-8"?>
      <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
          xmlns:xs="http://www.w3.org/2001/XMLSchema"
          exclude-result-prefixes="#all"
          version="3.0">
      
        <xsl:param name="eingabe-datei" as="xs:string">datei.txt</xsl:param>
      
        <xsl:param name="markierung" as="xs:string">KAPITEL</xsl:param>
      
        <xsl:param name="position" as="xs:integer" select="3"/>
      
        <xsl:output method="text"/>
      
        <xsl:template match="/" name="xsl:initial-template">
           <xsl:for-each-group select="unparsed-text-lines($eingabe-datei)" group-starting-with=".[. = $markierung]">
               <xsl:if test="position() = $position + 1">
                   <xsl:value-of select="current-group()" separator="
      "/>
               </xsl:if>
           </xsl:for-each-group>
        </xsl:template>
      
      </xsl:stylesheet>
      Kommandzeilenargumente für Saxon dann `-it -xsl:xslt.xsl -o:ausgabe.txt`.


      Comment


      • #4
        Hallo Martin Honnen

        Die Bedingungen sind leider so wie sie sind.

        Zum Verständnis, hier noch folgende Angaben.

        Buch | Gedicht sind identische Vorgaben.
        Innerhalb der Zeilenabfolge, gibt es schon strukturierte Vorgaben die dann in xslt weiter transformiert werden!
        Bei diesen Transformationen werden aus strukturellen Gründen immer wieder Blindgänger (siehe Bsp. aus anderen Kapiteln etc. mitgerissen/Mehrfachvorkommnisse).
        Dies gilt es nun auszumerzen.

        - Beispel: Mehrfachvorkomnisse
        Autor:\r\n (Zeileninhalt)!
        Max Mustermann\r\n (Zeileninhalt)!

        (Zeileninhalt)! Mehrfach- Vorkommnisse, nach Buchtitel und nach Kapitel.

        Demnach dürfen in Kapitel 5 nach Regex/Auswertung keine andersweitigen Autoren erscheinen. (nur Autoren aus Kapitel 5)

        BUCHTITEL und KAPITEL oder KOMPENDIUM und GEDICHT, sind die einzigen Ankerpunkte, die hier zur Aufgabe gestellt sind!

        xslt/Regex: Suche Zeilenanfang/Grossbuchstaben = KAPITEL[5] oder ähnlich
        xslt/Regex: bringe Folgezeilen nach (KAPITEL[5]) oder ähnlich
        xslt/Regex: output = copy of KAPITEL[5] 1:1 !


        mfg

        Karl_Heg






        Comment


        • #5
          Man kann statt der Suche nach
          Code:
          group-starting-with=".[. = $markierung]"
          für den exakten Vergleich natürlich auch
          Code:
          group-starting-with=".[starts-with(., $markierung)]"
          für den Vergleich des Zeileanfangs nehmen.

          Aber so mit einem bekannten Wort wie "KAPITEL" eine Struktur existiert, kann man die mit dem gegebenen Beispiel verarbeiten. Wann/wie BUCHTITEL oder KOMPENDIUM verarbeitet werden müssen, habe ich bis jetzt nicht verstanden, das Beispiel nimmt einfach an, dass vor dem ersten KAPITEL eine andere Struktur existiert, die dann aber durch den Vergleich von position() = $position + 1 ignoriert bzw. übersprungen wird.

          Comment


          • #6
            Hallo Martin Honnen
            Vielen Dank.
            Habe soeben die neue Version Saxparser PE bestellt, um mit xslt auf 3.0 umzustellen und Deinen Vorschlag zu testen.
            Soweit alles ok. Du hast den richtigen Ansatz geliefert.
            Gruss
            Karl_Heg






            Comment


            • #7
              XSLT 3 kann aber auch die kostenlose HE Edition mit Saxon 9.8 oder 9.9 oder 10, zu finden auf Sourceforge https://sourceforge.net/projects/saxon/files/Saxon-HE/

              Comment


              • #8
                Hallo Martin Honnen
                Respekt, Du hast mir genau die richtige Lösung geliefert.
                Ich habe die gesamte Transformation in ein Batch- File gelegt und musste folgende Modifikationen vornehmen.

                - Als sourceQuelle, wird ein dummi.xml benötigt.
                - In der Ausgabe habe ich Zeilenumbrüche \r\n eingebaut!

                -------------------------------------
                Mit nachstehendem Batch- File (java -jar....etc. zwingend in eine Zeile bringen), habe ich folgendes Resultat erziehlt

                at_echo off
                java -jar C:/Saxon/SaxonPE10-3J/saxon-pe-10.3.jar -t
                -s:C:/Users/karl/Documents/Sax_10_3/dummi_sax.xml
                -xsl:C:/Users/karl/Documents/Sax_10_3/book2_kapitel.xsl
                -o:C:/Users/karl/Documents/Sax_10_3/book_kapitel_outp.txt
                pause
                -----------------------------------
                book_kapitel_outp.txt: (Resultat!)
                KAPITEL
                Zeileninhalt
                Zeileninhalt
                Zeileninhalt
                Zeilen- Anzahl je nach Ausgabe varierend 03
                ---------------------------------
                Anfänglich hatte ich mit folgendem Fehler zu kämpfen
                SXXP0003 Error reported by XML parser:
                Dieser Fehler ist Internetweit bekannt.
                Plötzlich ist mir aufgefallen, dass in der Abfolge source/xsl/output, mein dummi_sax.xml
                gar nicht miteinbezogen ist.

                <?xml version="1.0" encoding="utf-8"?>
                <dummi>
                <dummi/>
                </dummi>
                ----------------------------------------
                Das Quelldokument *.txt to *.txt, wird erst in der xsl/- Stufe eingelesen!
                ----------------------------------------
                Ausgabe ohne Zeilenumbrüche: <xsl:value-of select="current-group()" separator=" "/>
                Ausgabe mit Zeilenumbrüchen: <xsl:value-of select="current-group()" separator="&#xd; "/>
                Von Deinen Optionen habe ich folgende eingesetzt: group-starting-with=".[starts-with(., $markierung)]

                Alles in allem, hast Du mir wieder ein Volltreffer geliefert. Recht herzlichen Dank!
                In Sache Programmieren, bin ich als mittelständler wieder einen grossen Schritt weitergekommen.
                PS: die reale Input Datei, ist ein textbasiertes, internationales x-change Format. (even/odd getaktet)
                mfg

                Karl_Heg

                Comment


                • #9
                  Ein XML-Dokument und die Option "-s" benötigst du wie gesagt nicht, wenn du die Option "-it" nutzt, die dann einfach die Verarbeitung durch Aufruf des Templates mit den Namen "xsl:initial-template" startet.

                  Comment


                  • #10
                    Danke Martin

                    Batch- File:

                    java -jar C:/Saxon/SaxonPE10-3J/saxon-pe-10.3.jar -it -xsl:C:/Users/karl/Documents/Sax_10_3/.....................etc....................

                    xslt_ Output:

                    <xslutput method="text"/>
                    <xsl:template match="/" name="xsl:initial-template">
                    <xsl:for-each-group select="unparsed-text-lines($eingabe-datei)" group-starting-with=".[starts-with(., $markierung)]">
                    <xsl:if test="position() = $position + 1">
                    <xsl:value-of select="current-group()" separator="&#xd; "/>
                    </xsl:if>
                    </xsl:for-each-group>
                    </xsl:template>

                    Result Batch:

                    Drücken Sie eine beliebige Taste . . . (einzige Rückmeldung), somit Fehlerfrei.

                    Alles läuft einwandfrei.

                    Was doch zwei Tippfehler alles bewirken können.

                    Liebe Grüsse aus dem Bayrischen Wald.

                    Karl_Heg

                    Comment

                    Working...
                    X