XSLT:如何生成每行 3 个单元格的 HTML 表格 [英] XSLT: How to generate an HTML table with 3 cells per row

查看:40
本文介绍了XSLT:如何生成每行 3 个单元格的 HTML 表格的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我按照 这篇来自 StackOverflow 的帖子

但我想将我的数据分布在一个 HTML 表格中,每行三个单元格.我更改了帖子中 XSLT 样式表中 sibling 的数字和 position 的计算,但似乎不起作用.

But I want to distribute my data in an HTML table with three cells per row. I changed the numbers for sibling and the calculation for position in the XSLT stylesheet from the post but it doesn't seem to work.

这是我的 XML 源:

This is my XML source:

<?xml version="1.0" encoding="UTF-8"?>
<report>
    <frontmatter>
        <title>Relatório da 4ª Sessão Intercalar</title>
        <subtitle>Projecto Integrado de Engenharia de Linguagens</subtitle>

        <authors>
            <author>
                <name>Marina Mac</name>
                <nident>pg999</nident>
                <email>pg999@minho.pt</email>
                <url>https://www.linkedin.com</url>
                <affil>Universidade do Minho</affil>
                <photo>source/img/authors/marina.png</photo>
            </author>
            <author>
                <name>Nuno Vie</name>
                <nident>pg998</nident>
                <email>pg998@minho.pt</email>
                <url>https://www.linkedin.com</url>
                <photo>source/img/authors/nuno.jpg</photo>
                <affil>Universidade do Minho</affil>
            </author>
            <author>
                <name>Damien Va</name>
                <nident>pg997</nident>
                <photo>source/img/authors/damien.jpg</photo>
                <url>https://www.linkedin.com</url>
                <email>pg997@minho.pt</email>
                <affil>Universidade do Minho</affil>
            </author>
            <author>
                <name>Tiago Mach</name>
                <nident>pg996</nident>
                <email>pg996@minho.pt</email>
                <url>https://www.linkedin.com</url>
                <affil>Universidade do Minho</affil>
                <photo>source/img/authors/marina.png</photo>
            </author>
            <author>
                <name>Manuel Vie</name>
                <nident>pg995</nident>
                <email>pg995@minho.pt</email>
                <url>https://www.linkedin.com</url>
                <photo>source/img/authors/nuno.jpg</photo>
                <affil>Universidade do Minho</affil>
            </author>
            <author>
                <name>Damien Vim</name>
                <nident>pg994</nident>
                <photo>source/img/authors/damien.jpg</photo>
                <url>https://www.linkedin.com</url>
                <email>pg994@alunos.uminho.pt</email>
                <affil>Universidade do Minho</affil>
            </author>
        </authors>
    </frontmatter>
</report>

这是我的 XSLT 代码,它不符合我的要求:

And this is my XSLT code which does not do what I want:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    exclude-result-prefixes="xs" version="2.0">

    <xsl:output indent="yes"/>

    <xsl:template match="/report">
        <html>
            <head>
                <meta charset="utf-8"/>
                <title><xsl:value-of select="frontmatter/title"/></title>
            </head>
            <body>
                <xsl:apply-templates select="frontmatter"/>
            </body>
        </html>
    </xsl:template>

    <xsl:template match="frontmatter" >
        <table width="100%">
            <tr align="center">
                <td>
                    <h1><xsl:value-of select="title"/></h1>
                </td>
            </tr>
            <xsl:if test="subtitle != '' ">
                <tr align="center">
                    <td>
                        <xsl:value-of select="subtitle"/>
                    </td>
                </tr>
            </xsl:if>
        </table>
        <hr width="90%"/>
        <h2>Autores</h2>
        <table width="90%" align="center">
            <xsl:apply-templates select="authors/author[position() mod 2 = 1]"/>
        </table>
    </xsl:template>

    <xsl:template match="authors/author">
        <tr>
            <xsl:for-each select=". | following-sibling::author[1]" >
                <td>
                    <p><xsl:value-of select="name"></xsl:value-of></p>
                </td>
            </xsl:for-each>
            <xsl:if test="not(following-sibling::author)">
                <td/>
                <td/>
            </xsl:if>
        </tr>
    </xsl:template>

</xsl:stylesheet>

如何修复我的样式表,使其生成每行 3 个单元格的 HTML 表格?

How could I fix my stylesheet so that it generates an HTML table with 3 cells per row?

推荐答案

如果你有 6 个作者,我假设你期待这样的结果:

I'm assuming that you expect a result like this, if you have 6 authors:

  <table width="90%" align="center" border="1">
     <tr>
        <td>Marina Machado</td>
        <td>Damien Vaz</td>
        <td>Manuel Vieira</td>
     </tr>
     <tr>
        <td>Nuno Vieira</td>
        <td>Tiago Machado</td>
        <td>Damien Vaz</td>
     </tr>
  </table>

而且,如果您有三位或更多作者,您将始终拥有三栏.少于三列的唯一情况是您有零位、一位或两位作者.这些列将从从左到右填充,因此如果您有 7 个作者,那么最后一行的第一列中将只有一个作者.

And that if you have three authors or more you will always have three columns. The only case where you'll have less than three columns is if you have zero, one or two authors. The columns will be filled from left to right, so if you have 7 authors, the last row will only have one author in the first column.

这将是五位作者的结果:

This would be the result with five authors:

  <table width="90%" align="center" border="1">
     <tr>
        <td>Marina Machado</td>
        <td>Damien Vaz</td>
        <td>Manuel Vieira</td>
     </tr>
     <tr>
        <td>Nuno Vieira</td>
        <td>Tiago Machado</td>
     </tr>
  </table>

如果您有七个,则会创建一个新行:

And if you have seven, a new row will be created:

  <table width="90%" align="center" border="1">
     <tr>
        <td>Marina Machado</td>
        <td>Damien Vaz</td>
        <td>Manuel Vieira</td>
     </tr>
     <tr>
        <td>Nuno Vieira</td>
        <td>Tiago Machado</td>
        <td>William Shakespeare</td>
     </tr>
     <tr>
        <td>Heitor Villa-Lobos</td>
     </tr>
  </table>

您可以使用此样式表(我将其简化为代码的基本部分以处理分组问题 - 您可以稍后将其重新调整为您的代码):

You can generate a HTML table that satisfies those requirements, given your source XML, with this stylesheet (I reduced it to the essential parts of your code to deal with the grouping problem - you can later readapt it to your code):

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output indent="yes"/>
    <xsl:strip-space elements="*"/>

    <xsl:param name="cols">3</xsl:param> <!-- set the number of rows here -->

    <xsl:template match="frontmatter" >
        <table width="90%" align="center" border="1">
            <xsl:apply-templates select="authors/author[position() mod $cols = 1 or position() = 1]" mode="row"/>
        </table>
    </xsl:template>

    <xsl:template match="authors/author" mode="row">
        <tr>
            <xsl:apply-templates select=". | following-sibling::author[position() &lt; $cols]" mode="cell"/>
        </tr>
    </xsl:template>

    <xsl:template match="authors/author" mode="cell">
        <td>
            <xsl:value-of select="name"/>
        </td>
    </xsl:template>

</xsl:stylesheet>

如果您决定将作者分布在不同数量的列中,您可以传递具有不同值的 cols 参数或替换参数 <xsl:param 中的值name="cols">3</xsl:param> 与另一个值.例如,如果您将其更改为 4 列,它将像这样分发您的作者:

If you decide to distribute the authors in a different amount of columns, you can either pass a cols parameter with a different value or replace the value in the parameter <xsl:param name="cols">3</xsl:param> with another value. For example, if you change it to 4 columns, it will distribute your authors like this:

<table width="90%" align="center" border="1">
   <tr>
      <td>Marina Machado</td>
      <td>Nuno Vieira</td>
      <td>Damien Vaz</td>
      <td>Tiago Machado</td>
   </tr>
   <tr>
      <td>Manuel Vieira</td>
      <td>Damien Vaz</td>
   </tr>
</table>

在这个模板中计算行数:

The number of rows is calculated in this template:

<xsl:template match="frontmatter" >
    <table width="90%" align="center" border="1">
        <xsl:apply-templates select="authors/author[position() mod $cols = 1 or position() = 1]" mode="row"/>
    </table>
</xsl:template>

XPath 表达式选择位置除以列数余数为1的作者.对于三列,它将选择 元素编号 1, 4, 7, 10, ... 它还将选择 last 元素(可能不是其中之一).它将调用带有 mode="row" 标记的第一个 author 模板.

The XPath expression selects the authors whose position divided by the number of columns has a remainder of one. For three columns, it will select <author> elements number 1, 4, 7, 10, ... It will also select the last element (which might not be one of those). It will call the first author template tagged with mode="row".

该模板选择将包含每行单元格数据的元素:

That template selects the elements that will contain the data for the cells of each row:

<xsl:template match="authors/author" mode="row">
    <tr>
        <xsl:apply-templates select=". | following-sibling::author[position() &lt; $cols]" mode="cell"/>
    </tr>
</xsl:template>

它将选择当前 author (.),以及距离$cols的以下兄弟> - 1.如果$cols为3,则选择当前author和下两个authors(如果存在).这样,它将选择将放置在一行中的所有元素.例如,如果前一个模板选择了元素 1 和 4(用于 3 列),则此模板将为第一列选择元素 1(当前)、2 和 3,并为第二列选择元素 4(当前)、5 和 6.此选择将用于应用 mode="cell" 模板,该模板仅在 中打印作者的 name 子元素> 阻止.

It will select the current author (.), and the following siblings at a distance of $cols - 1. If the $cols is 3, then it will select the current author and the next two authors if they exist. That way, it will select all elements that will be placed in a row. For example, if the previous template selected elements 1 and 4 (for 3 columns), this template will select elements 1 (current), 2 and 3 for the first column, and elements 4 (current), 5 and 6 for the second. This selection will be used to apply the mode="cell" template which simply prints the name child element of the author inside a <td> block.

此解决方案适用于 XSLT 1.0 2.0.

This solution works with XSLT 1.0 or 2.0.

您可以在此 XSLT Fiddle

You can see the code working in this XSLT Fiddle

这篇关于XSLT:如何生成每行 3 个单元格的 HTML 表格的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆