2011-01-07 3 views
5

Ich überprüfe, ob jemand ein XSLT herumliegen hat, das HTML-Tabellen in CALS umwandelt. Ich habe eine Menge Material dafür gefunden, in die andere Richtung zu gehen (CALS in HTML), aber nicht aus HTML. Ich dachte, jemand hätte das schon mal gemacht, also muss ich das Rad nicht neu erfinden. Ich bin nicht auf der Suche nach einer vollständigen Lösung. Nur ein Ausgangspunkt.HTML zu CALS-Tabellen?

Wenn ich weit genug allein komme, werde ich es für zukünftige Referenz veröffentlichen.

+1

Bitte, ein kleines Beispiel nennen: 1. die (X) HTML. 2. Das gewünschte Ergebnis. Viele Leute, mich eingeschlossen, wissen nicht, was eine CALS-Tabelle ist. –

+1

Von der letzten OASIS [spec] (http://www.oasis-open.org/specs/tm9901.html) sieht es so aus, als wäre die Transformation meistens 'tr' ->' row' und 'td' ->' entry' –

+0

Ich stellte gerade die Frage, um zu sehen, ob jemand etwas archiviert hatte. Ich werde in Kürze einen Beispielcode hinzufügen. – Jeff

Antwort

4

ich mit einer viel einfacheren Lösung zu kommen haben als das, was zu @Flack verbunden:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 
<xsl:template match="tbody"> 
    <xsl:variable name="maxColumns"> 
     <xsl:for-each select="tr"> 
      <xsl:sort select="sum(td/@colspan) + count(td[not(@colspan)])" data-type="number"/> 
      <xsl:if test="position() = last()"> 
       <xsl:value-of select="sum(td/@colspan) + count(td[not(@colspan)])"/> 
      </xsl:if> 
     </xsl:for-each> 
    </xsl:variable> 
    <tgroup> 
     <xsl:attribute name="cols"> 
      <xsl:value-of select="$maxColumns"/> 
     </xsl:attribute> 
     <xsl:apply-templates select="@*|node()"/> 
    </tgroup> 
</xsl:template> 

<xsl:template match="td[@colspan > 1]"> 
    <entry> 
     <xsl:attribute name="namest"> 
      <xsl:value-of select="sum(preceding-sibling::td/@colspan) + count(preceding-sibling::td[not(@colspan)]) + 1"/> 
     </xsl:attribute> 
     <xsl:attribute name="nameend"> 
      <xsl:value-of select="sum(preceding-sibling::td/@colspan) + count(preceding-sibling::td[not(@colspan)]) + @colspan"/> 
     </xsl:attribute> 
     <xsl:apply-templates select="@*[name() != 'colspan']|node()"/> 
    </entry> 
</xsl:template> 

<xsl:template match="tr"> 
    <row> 
     <xsl:apply-templates select="@*|node()"/> 
    </row> 
</xsl:template> 

<xsl:template match="td"> 
    <entry> 
     <xsl:apply-templates select="@*|node()"/> 
    </entry> 
</xsl:template> 

<xsl:template match="td/@rowspan"> 
    <xsl:attribute name="morerows"> 
     <xsl:value-of select=". - 1"/> 
    </xsl:attribute> 
</xsl:template> 

<!-- fallback rule --> 
<xsl:template match="@*|node()"> 
    <xsl:copy> 
     <xsl:apply-templates select="@*|node()"/> 
    </xsl:copy> 
</xsl:template> 
</xsl:stylesheet> 

Es gibt zwei schwierige Punkte. Zunächst benötigt eine CALS-Tabelle ein tgroup/@ cols Attribut, das die Anzahl der Spalten enthält. Also müssen wir die maximale Anzahl von Zellen in einer Zeile in der XHTML-Tabelle finden - aber wir müssen colspan Deklarationen beachten, so dass eine Zelle mit colspan > 1 die richtige Anzahl von Spalten erstellt! Die erste Vorlage in meinem Stylesheet macht genau das, basierend auf der Antwort von @Tim C auf die max cells per row problem.

Ein weiteres Problem besteht darin, dass für mehrspaltige Zellen XHTML sagt „diese Zelle 3 Spalten breit“ (colspan = „3“), während CALS wird sagen: „diese Zelle beginnt in Spalte 2 und endet in Spalte 4“ (namest = "2" nameend = "4"). Diese Umwandlung erfolgt in der zweiten Vorlage im Stylesheet.

Der Rest ist in der Tat ziemlich einfach. Das Stylesheet behandelt keine Details wie das Ändern von style = "width: 50%" in width = "50%" usw. aber das sind relativ häufige Probleme, glaube ich.

+0

Danke dafür! Mein Projekt änderte sich und hatte keine Chance mehr, darauf zurück zu kommen. Ich werde das im Hinterkopf behalten, da ich weiß, dass es wieder hochkommen wird. Vielen Dank! – Jeff