2011-01-07 13 views
5

Sprawdzam, czy ktoś ma XSLT r. Wokół, który przekształca tabele HTML na CALS. Znalazłem wiele materiałów na temat pójścia w drugą stronę (CALS do HTML), ale nie z HTML. Myślałem, że ktoś mógł to zrobić wcześniej, więc nie muszę wymyślać koła. Nie szukam kompletnego rozwiązania. Tylko punkt wyjścia.HTML na stoły CALS?

Jeśli zdobędę wystarczająco dużo samodzielnie, opublikuję go w celu późniejszego wykorzystania.

+1

Proszę podać mały przykład: 1. (X) HTML. 2. Pożądany wynik. Wiele osób, łącznie ze mną, nie wie, co to jest tabela CALS. –

+1

Od ostatniego OASIS [spec] (http://www.oasis-open.org/specs/tm9901.html) wygląda na to, że transformacja jest w większości 'tr' ->' row' i 'td' ->' entry' –

+0

Po prostu zadawałem pytanie, czy ktoś miał coś zarchiwizowane. Wkrótce dodam przykładowy kod. – Jeff

Odpowiedz

4

mam wymyślić znacznie prostsze rozwiązanie niż to, co @Flack związane z:

<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> 

Istnieją dwa trudne punkty. Po pierwsze, tabela CALS wymaga atrybutu tgroup/@ cols, który zawiera liczbę kolumn. Dlatego musimy znaleźć maksymalną liczbę komórek w jednym wierszu w tabeli XHTML - ale musimy uważać na deklaracje colspan, aby komórka z colspan > 1 tworzy odpowiednią liczbę kolumn! Pierwszy szablon w moim arkuszu stylów właśnie to, na podstawie odpowiedzi @Tim C na max cells per row problem.

Innym problemem jest to, że dla komórek wielu kolumn XHTML mówi „komórka ta jest szeroko 3 kolumny” (colspan = „3”) podczas CALS powie „komórka ta zaczyna się w kolumnie 2 i kończy się na kolumnie (4” namest = "2" nameend = "4"). Ta transformacja jest wykonywana w drugim szablonie w arkuszu stylów.

Reszta jest rzeczywiście dość prosta. Arkusz stylów nie zajmuje się takimi szczegółami, jak zmiana stylu = "szerokość: 50%" na szerokość = "50%" itd., Ale sądzę, że są to stosunkowo częste problemy.

+0

Dzięki za to! Mój projekt się zmienił i nie miałem szansy wrócić do niego ponownie. Na pewno będę o tym pamiętał, ponieważ wiem, że znowu się pojawi. Dzięki! – Jeff