Announcement

Collapse
No announcement yet.

Ist folgendes Transformations-Problem mit XSLT zu lösen?

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

  • Ist folgendes Transformations-Problem mit XSLT zu lösen?

    Hallo,

    ich muß XML-Dateien umwandeln und stehe dabei vor der Frage, ob ich das in dem konkreten Fall mit XSLT überhaupt lösen kann.

    Folgendes ist die Ausgangssituation:
    Code:
    <content>
            <line number="1">Lorem ipsum dolor sit amet, consetetur sadipscing elitr, </line>
            <line number="2">sed diam nonumy eirmod tempor invidunt ut la-</line>
            <line number="3">bore et dolore magna aliquyam erat, sed diam voluptua.</line>
            <line number="4"/>
            <line number="5">At vero eos et accusam et justo duo dolores et ea rebum. Stet cli-</line>
            <line number="6">ta kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.</line>
            <line number="7"/>
            <line number="8">Lorem ipsum dolor sit amet, </line>
    </content>
    Zu sagen ist, dass die leeren Zeilen auch woanders sein können, ihre Position muß berechnet werden.

    Folgendes sind die Aufgaben:
    a) Jeweils einzelne "line" zu Absätzen zusammenzufassen. Absätze werden durch leere "line" getrennt. In diesem Fall also "line" 1-3, 5-6 und 8.

    b) Bei den Absätzen die Silbentrennung zu entfernen.

    Meine Grundkenntnisse von XSLT reichen leider nicht für diese Fragen. Daher meine Bitte um eine Einschätzung und um Tipps, in welche Richtung es gehen sollte.

    Danke!

  • #2
    Machbar ist das sicherlich, mit XSLT 2.0 und for-each-group auch elegant und kurz mittels for-each-group group-ending-with:
    Code:
    <xsl:stylesheet
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
      xmlns:xsd="http://www.w3.org/2001/XMLSchema"
      xmlns:mf="http://example.com/mf"
      exclude-result-prefixes="mf xsd"
      version="2.0">
      
      <xsl:output indent="yes"/>
      
      <xsl:template match="content">
        <xsl:copy>
          <xsl:for-each-group select="line" group-ending-with="line[not(node())]">
            <para>
              <xsl:apply-templates select="current-group()/node()"/>
            </para>
          </xsl:for-each-group>
        </xsl:copy>
      </xsl:template>
      
      <xsl:template match="line//text()[ends-with(., '-')]">
        <xsl:value-of select="substring(., 1, string-length(.) - 1)"/>
      </xsl:template>
      
    </xsl:stylesheet>
    Damit macht dann z.b. Saxon 9 (http://saxon.sourceforge.net/) aus
    Code:
    <content>
            <line number="1">Lorem ipsum dolor sit amet, consetetur sadipscing elitr, </line>
            <line number="2">sed diam nonumy eirmod tempor invidunt ut la-</line>
            <line number="3">bore et dolore magna aliquyam erat, sed diam voluptua.</line>
            <line number="4"/>
            <line number="5">At vero eos et accusam et justo duo dolores et ea rebum. Stet cli-</line>
            <line number="6">ta kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.</line>
            <line number="7"/>
            <line number="8">Lorem ipsum dolor sit amet, </line>
    </content>
    folgendes:
    Code:
    <?xml version="1.0" encoding="UTF-8"?>
    <content>
       <para>Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.</para>
       <para>At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.</para>
       <para>Lorem ipsum dolor sit amet, </para>
    </content>

    Comment


    • #3
      Ich sollte noch andere XSLT 2.0 Prozessoren nennen: XQSharp (http://www.xqsharp.com/), AltovaXML Tools (http://www.altova.com/altovaxml.html). Außerdem haben IBM (Websphere), Marklogic und Intel in ihren Webapplikationsservern XSLT 2.0 Unterstützung.

      Comment


      • #4
        Danke. Das sieht schon sehr gut aus.
        Nun habe ich noch das Problem, dass ich dieses Template innerhalb eines anderen Templates anwenden muß.
        Ein Code wie
        Code:
        <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions">
        	<xsl:template match="Inhalt">
        		<Inhalt>
        			<xsl:apply-templates select="content">
        				<xsl:copy>
        					<xsl:for-each-group select="line" group-ending-with="line[not(node())]">
        						<par>
        							<xsl:apply-templates select="current-group()/node()"/>
        						</par>
        					</xsl:for-each-group>
        				</xsl:copy>
        			</xsl:apply-templates>
        			<xsl:apply-templates select="line//text()[ends-with(., '-')]">
        				<xsl:value-of select="substring(., 1, string-length(.) - 1)"/>
        			</xsl:apply-templates>
        		</Inhalt>
        	</xsl:template>
        </xsl:stylesheet>
        funktioniert nicht. Ich fürchte aber, dass ich dabei noch nicht den Aufruf von Templates bei XSL verstanden habe.

        Comment


        • #5
          Die Templates, die ich in meinem Code gepostet habe, solltest du schon so belassen. Wenn es weitere Elemente in deinen XML-Dokument gibt, dann braucht man eventuell weitere Templates, aber wenn du damit Hilfe brauchst, dann poste Beispiele, wie ein Eingabedokument und das dazugehörige Resultat aussehen soll.

          Comment


          • #6
            Fehler gefunden!
            ein einfaches
            <xsl:apply-templates />
            reicht ja.

            Comment


            • #7
              Einschränken der for-each-group auf bestimmte Zeilen

              Hallo,

              wenn ich im oberen Bsp. nun nicht alle Zeilen bearbeiten will, sondern nur die mit number=3 bis number =7: wie mache ich das?

              Danke!

              Comment


              • #8
                Code:
                <xsl:for-each-group select="line[@number &gt;= 3 and @number &lt;= 7]"
                erlaubt dir die Selektion.

                Comment

                Working...
                X