Идентификация определенных ячеек XHTML с использованием XSLT и изменение их атрибутов после их нахождения - PullRequest
2 голосов
/ 14 декабря 2011

У меня проблема с преобразованием входного XHTML-документа, чтобы лучше отображать страницу на мобильных устройствах. Каждый входной документ имеет множество таблиц HTML с определенным идентификатором. В одной такой таблице мне нужно идентифицировать ячейку, чтобы не только изменить ее атрибут «colspan», но и атрибуты «colspan» для ячеек по обе стороны от нее. Я не могу изменить входной HTML, это получено извне. Я могу только преобразовать это.

В каждом случае ячейки, которую я пытаюсь преобразовать, слева и справа от нее есть пустая ячейка, обе с атрибутом «colspan = 2». Мне нужно сделать так, чтобы эта средняя ячейка имела атрибут «colspan = 4», левая ячейка имела атрибут «colspan = 1», а правая ячейка была удалена.

Я использовал XSLT и до сих пор сумел добиться ряда других преобразований с моим документом, поэтому я знаю, что это должно быть как-то возможно. Пример таблицы приведен ниже.

Пример таблицы, которую я имею:

<html>
<body>
<table border="1">
<tr>
    <td>row 1, cell 1</td>
    <td>row 1, cell 2</td>
    <td>row 1, cell 3</td>
    <td>row 1, cell 4</td>
    <td>row 1, cell 5</td>
    </tr>
    <tr>
    <td colspan = "2">row 2, cell 1</td>
    <td>Cell I Need</td>
    <td colspan = "2">row 2, cell 3</td>
    </tr>
    <tr>
    <td>row 3, cell 1</td>
    <td>row 3, cell 2</td>
    <td>row 3, cell 3</td>
    <td>row 3, cell 4</td>
    <td>row 3, cell 5</td>
    </tr>
</table>

Таблица мне нужна:

    <table border="1">
<tr>
    <td>row 1, cell 1</td>
    <td>row 1, cell 2</td>
    <td>row 1, cell 3</td>
    <td>row 1, cell 4</td>
    <td>row 1, cell 5</td>
    </tr>
    <tr>
    <td colspan = "1">row 2, cell 1</td>
    <td colspan = "4">Cell I Need</td>
    </tr>
    <tr>
    <td>row 3, cell 1</td>
    <td>row 3, cell 2</td>
    <td>row 3, cell 3</td>
    <td>row 3, cell 4</td>
    <td>row 3, cell 5</td>
    </tr>
</table>
</body>
<html>

Будем весьма благодарны за любые предложения о том, как идентифицировать и преобразовать эту ячейку с использованием XSLT.

Большое спасибо, Кристиан

Ответы [ 2 ]

3 голосов
/ 14 декабря 2011

Очень простым способом:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="table">
        <xsl:copy>
            <xsl:copy-of select="@*" />
            <xsl:apply-templates select="tr" />
        </xsl:copy>
    </xsl:template>
    <xsl:template match="tr">
        <tr>
            <xsl:choose>
                <xsl:when test="count(td[@colspan='2'])=2 and count(td)=3">
                    <td colspan="1">
                        <xsl:copy-of select="td[1]/node()" />
                    </td> 
                    <td colspan="4">
                        <xsl:copy-of select="td[2]/node()" />                   
                    </td>
                </xsl:when>
                <xsl:otherwise>
                    <xsl:copy-of select="td" />
                </xsl:otherwise>
            </xsl:choose>
        </tr>
    </xsl:template>
</xsl:stylesheet>
3 голосов
/ 14 декабря 2011

Предполагая, что ячейки в таблице пусты (я предполагаю, что «строка 2, ячейка 1» в вашем образце являются чисто аннотациями и фактически не отображаются в HTML), вы можете сопоставить строку таблицы спервая и третья ячейки пусты и имеют атрибуты colspan , например, так.

<xsl:template match="tr
   [td[1][@colspan !=''][not(text())]]
   [td[3][@colspan !=''][not(text())]]
   [not(td[4])]">

Затем вы можете объединить это с преобразованием идентичности, чтобы выполнить дополнительную обработку в этой строке.Вот полный XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   <xsl:output method="xml" indent="yes"/>

   <xsl:template match="tr[td[1][@colspan !=''][not(text())]][td[3][@colspan !=''][not(text())]][not(td[4])]">
      <xsl:copy>
         <xsl:variable name="colspan" select="sum(td/@colspan) + count(td[not(@colspan)]) - 1"/>
         <td/>
         <td colspan="{$colspan}">
            <xsl:apply-templates select="td[2]/@*|td[2]/node()"/>
         </td>
      </xsl:copy>
   </xsl:template>

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

Применительно к следующему входному XML

<html>
   <body>
      <table border="1">
         <tr>
            <td>row 1, cell 1</td>
            <td>row 1, cell 2</td>
            <td>row 1, cell 3</td>
            <td>row 1, cell 4</td>
            <td>row 1, cell 5</td>
         </tr>
         <tr>
            <td colspan="2"></td>
            <td>Cell I Need</td>
            <td colspan="2"></td>
         </tr>
         <tr>
            <td>row 3, cell 1</td>
            <td>row 3, cell 2</td>
            <td>row 3, cell 3</td>
            <td>row 3, cell 4</td>
            <td>row 3, cell 5</td>
         </tr>
      </table>
   </body>
</html>

Ниже выводится

<html>
   <body>
      <table border="1">
         <tr>
            <td>row 1, cell 1</td>
            <td>row 1, cell 2</td>
            <td>row 1, cell 3</td>
            <td>row 1, cell 4</td>
            <td>row 1, cell 5</td>
         </tr>
         <tr>
            <td />
            <td colspan="4">Cell I Need</td>
         </tr>
         <tr>
            <td>row 3, cell 1</td>
            <td>row 3, cell 2</td>
            <td>row 3, cell 3</td>
            <td>row 3, cell 4</td>
            <td>row 3, cell 5</td>
         </tr>
      </table>
   </body>
</html>

Примечание. Я позволил некоторую гибкостьу вас более 5 ячеек, и colspan будет отличаться от 2. В этом случае

Также обратите внимание, что на самом деле необязательно иметь colspan = "1" показ.Если у вас есть конкретное требование включить это в вывод, это, очевидно, несложно сделать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...