odf->docbook

DC-7C

Mitglied
Hallo Allerseits!

ich muß Dateien vom odf mittels xslt in docbook konvertieren. Einiges geht ohne Probleme, einiges hat mir bereits ein paar graue Haare gekostet.

Mein Hauptproblem derzeit:

folgendes Abscnitt:

Code:
<text:p text:style-name="chapter">
			<text:h text:style-name="Kapitel_Titel">Kapiteltitel</text:h>
			<text:h text:style-name="Kapitel_Untertitel">Untertitel</text:h>
			<text:p text:style-name="para">Text im Kapitel</text:p>
			<text:h text:style-name="section_title1">Abschnitt Titel Level 1</text:h>
			<text:h text:style-name="section_subtitle1">Abschnitt Untertitel Level 1</text:h>
			<text:p text:style-name="para">Unterkapitel im Kapitel mit ein wenig Text</text:p>
			<text:h text:style-name="section_title2">Abschnitt Titel Level 2</text:h>
			<text:h text:style-name="section_subtitle2">Abschnitt Untertitel Level 2</text:h>
			<text:h text:style-name="section_title3">Abschnitt Titel Level 3</text:h>
			<text:h text:style-name="section_subtitle3">Abschnitt Untertitel Level 3</text:h>
			<text:h text:style-name="section_title4">Abschnitt Titel Level 4</text:h>
			<text:h text:style-name="section_subtitle4">Abschnitt Untertitel Level 4</text:h>
			<text:p text:style-name="para">Irgendein Text.</text:p>
		</text:p>

muß nach der Konvertierung so aussehen:

Code:
<chapter>
		<title>Kapiteltitel</title>
		<subtitle>Untertitel</subtitle>
		<para>Text im Kapitel</para>
		<sect1>
			<title>Abschnitt Titel Level 1</title>
			<subtitle>Abschnitt Untertitel Level 1</subtitle>
			<para>Unterkapitel im Kapitel mit ein wenig Text</para>
			<sect2>
				<title>Abschnitt Titel Level 2</title>
				<subtitle>Abschnitt Untertitel Level 2</subtitle>
				<sect3>
					<title>Abschnitt Titel Level 3</title>
					<subtitle>Abschnitt Untertitel Level 3</subtitle>
					<sect4>
						<title>Abschnitt Titel Level 4</title>
						<subtitle>Abschnitt Untertitel Level 4</subtitle>
						<para>Irgendein Text.</para>
					</sect4>
				</sect3>
			</sect2>
		</sect1>
	</chapter>

Ich kann mir zwar merken, wo ich z.B. den Tag <sect2> setzen kann, kann mir aber im Moment nicht vorstellen, wie soll xslt erkennen wo dieses Tag geschlossen werden muß? :( Kann mir jemand helfen?

Danke im voraus!
 
Hi!

Ich fragte nur weil ich mit Version 2.0 wenig gearbeitet habe und mein Lösungsansatz auf dem Vorgänger beruht - dadurch leider etwas komplex geraten ist.
Dennoch: Du musst nicht direkt wissen, wann ein Element zu schließen ist - es ist ja auch nicht möglich, ein öffnendes "Tag" zu setzen und in einem völlig anderen Kontext das schließende Äquivalent.
IMHO ist das einzige was hier hilft eine Rekursion, und das wird auch in 2.0 nicht anders sein...
XML:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:transform version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:odf="odf"
    xmlns="docbook:uri"
    exclude-result-prefixes="odf">

  <xsl:template match="/odf:p"> <!-- XPath muss natürlich angepasst werden -->
   <chapter>
    <title><xsl:value-of select="./odf:h[position() = 1]"/></title>
    <subtitle><xsl:value-of select="./odf:h[position() = 2]"/></subtitle>
    <para><xsl:value-of select="./odf:p[position() = 1]"/></para>
    <xsl:call-template name="section">
     <xsl:with-param name="iter" select="1"/>
    </xsl:call-template>
   </chapter>
  </xsl:template>

  <xsl:template name="section">
   <xsl:param name="iter"/>
   <xsl:variable name="sect" select="concat('sect', $iter)"/>
   <xsl:if test="./odf:h[@odf:style-name = concat('section_title', $iter)]">
    <xsl:element name="{$sect}">
     <title><xsl:value-of select="./odf:h[@odf:style-name = concat('section_title', $iter)]"/></title>
     <xsl:for-each select="./child::*[self::odf:h or self::odf:p]">
      <xsl:if test="@odf:style-name = concat('section_subtitle', $iter)">
       <xsl:variable name="position" select="position()"/>
       <subtitle><xsl:value-of select="."/></subtitle>
       <para><xsl:value-of select="../child::*[(self::odf:h or self::odf:p) and position() = $position]"/></para>
      </xsl:if>
     </xsl:for-each>
     <xsl:call-template name="section">
      <xsl:with-param name="iter" select="$iter + 1"/>
     </xsl:call-template>
    </xsl:element>
   </xsl:if>
  </xsl:template>

</xsl:transform>
Die richtigen URIs habe ich einfach mal Unterschlagen. Wie Du siehst ist vor allem das Adressieren der Paragraphen <p> ein wenig Umständlich...
Aber nicht nur in XSL-T 2.0 wird es - dank XPath 2.0 - eine einfachere Lösung geben, auch hier läßt sich bestimmt noch was verbessern oder gar ein Weg finden der noch einfacher ist :)

Gruß
Enum
 
Zurück