XSL中实现HTML的表格自动换行

博客展示了一段XML数据,包含多个movie元素。目标是将这些数据按每行5个元素的格式展示。通过一段XSL代码实现该效果,代码中定义了变量和模板,利用XSL的功能将XML数据转换为HTML表格形式输出。

xml数据如:
<root>
<movie>1</movie>
<movie>2</movie>
<movie>3</movie>
<movie>4</movie>
<movie>5</movie>
<movie>6</movie>
<movie>7</movie>
<movie>8</movie>
<movie>9</movie>
<movie>10</movie>
<movie>11</movie>
<movie>12</movie>
</root>

要达到的效果:
1     2     3     4      5
6     7     8     9     10
11  12

XSL代码:
<?xml version="1.0" encoding="GB2312"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:variable name="Rows">5</xsl:variable>

<xsl:template match="//root">
  <table>
    <xsl:for-each select="movie[position() mod $Rows=1]">
      <tr>
        <xsl:apply-templates select=".|following-sibling::*[position()&lt;$Rows]"/>
      </tr>
    </xsl:for-each>
  </table>
</xsl:template>

<xsl:template match="movie">
  <td>
    <xsl:value-of select="."/>
  </td>
</xsl:template>

</xsl:stylesheet>

<think>我们正在处理的是XSL-FO(格式化对象)表格中的情况。问题描述:在<fo:table-row>中,当select查询返回的NoInland字段为空字符串时,我们希望显示一个空格(而不是什么都不显示)。 根据XSL-FO,我们通常在表格单元格<fo:table-cell>中使用<fo:block>来放置内容。如果数据为空,我们可以使用条件判断来输出空格。 思路: 1. 在XSLT中,我们可以使用<xsl:choose>或<xsl:if>来判断NoInland的值。 2. 如果NoInland是空字符串,则输出一个空格(或者使用 的Unicode,但注意在XSL-FO中,空格会正常显示,而 不是直接使用的,我们可以用空格字符或使用Unicode字符)。 注意:在XSL-FO中,我们直接输出空格字符即可,因为FO处理器会将其视为一个空格并进行渲染。 具体步骤: 假设我们有一个变量或直接访问NoInland字段,例如:<xsl:value-of select="NoInland"/>。 我们可以这样写: 使用<xsl:choose>: <xsl:choose> <xsl:when test="NoInland = ''"> <!-- 或者 test="normalize-space(NoInland)=''" 如果考虑空白字符 --> <fo:block> </fo:block> <!-- 这里放一个空格 --> </xsl:when> <xsl:otherwise> <fo:block><xsl:value-of select="NoInland"/></fo:block> </xsl:otherwise> </xsl:choose> 或者更简洁地使用<xsl:if>: <fo:block> <xsl:if test="NoInland = ''"> </xsl:if> <xsl:value-of select="NoInland"/> </fo:block> 但是上面的<xsl:if>方式有一个问题:当NoInland为空时,我们输出一个空格,否则输出NoInland的值。但是注意,当NoInland不为空时,<xsl:value-of select="NoInland"/>会输出其值,而空的时候只输出空格。然而,如果NoInland有值,那么空格也会被输出,因为空格在<xsl:if>后面,所以这样写不行。 修正:我们可以这样: <fo:block> <xsl:choose> <xsl:when test="NoInland = ''"> </xsl:when> <xsl:otherwise><xsl:value-of select="NoInland"/></xsl:otherwise> </xsl:choose> </fo:block> 或者更简单的,使用: <fo:block> <xsl:value-of select="NoInland"/> </fo:block> 但是这样当NoInland为空时,就什么都不显示。所以我们需要在为空时显示空格,因此必须使用条件判断。 另外,我们也可以使用XSLT的一个技巧:利用字符串函数,当为空时用一个空格代替。 <fo:block> <xsl:value-of select="concat(NoInland, substring(' ', 1, not(NoInland!='')))"/> </fo:block> 但这种方法可能过于复杂,可读性差。所以还是推荐使用<xsl:choose>。 因此,在表格单元格中,我们可以这样写: <fo:table-cell> <fo:block> <xsl:choose> <xsl:when test="NoInland = '' or not(NoInland)"> <!-- 考虑到可能没有节点或者为空字符串 -->   <!-- 或者直接写一个空格,但使用 (不换行空格)可能更符合要求 --> </xsl:when> <xsl:otherwise> <xsl:value-of select="NoInland"/> </xsl:otherwise> </xsl:choose> </fo:block> </fo:table-cell> 解释: - 我们使用 (HTML中的 在XSL-FO中对应的Unicode字符)来表示一个不换行空格。在FO中,可以直接使用 ,因为FO处理器支持Unicode。 - 注意:在XSLT中,我们可以使用十进制字符引用(如 )或十六进制(如 )来表示不换行空格。 另外,我们也可以使用<xsl:text> </xsl:text>来输出空格,但注意普通的空格可能会在输出时被忽略(如果它是唯一的字符),而使用 可以确保显示。 所以,建议使用 来代表一个空格。 修改后的代码: <xsl:choose> <xsl:when test="normalize-space(NoInland)=''"> </xsl:when> <xsl:otherwise><xsl:value-of select="NoInland"/></xsl:otherwise> </xsl:choose> 这里使用了normalize-space()函数,可以去除字符串两端的空白,并且将内部的连续空白变成一个空格。这样,如果NoInland是空白字符串(包括空格、制表符等)也会被视为空,从而显示空格。但注意,如果NoInland本身包含空白字符,我们可能不想将其替换为空格,而是原样显示。所以根据需求,如果希望只有完全为空(或者空白)才替换,则使用normalize-space(NoInland)=''。 因此,根据你的需求,如果NoInland是空字符串(或者全是空白字符)时,我们显示一个空格(不换行空格),否则显示原内容。 示例代码片段: <fo:table-row> ...其他单元格... <fo:table-cell> <fo:block> <xsl:choose> <xsl:when test="normalize-space(NoInland)=''"> </xsl:when> <xsl:otherwise><xsl:value-of select="NoInland"/></xsl:otherwise> </xsl:choose> </fo:block> </fo:table-cell> ...其他单元格... </fo:table-row> 这样,当NoInland为空或空白字符串时,单元格内会显示一个空格,确保表格结构完整。 请注意:在XSL-FO中,如果单元格内容为空,可能会导致单元格边框不显示或样式问题,因此用一个空格占位是常见的做法。 希望这能解决你的问题。 </think>在 XSL-FO 表格中,当 `select` 查询的 `NoInland` 字段返回空字符串时,可通过以下方案强制显示为空格(保留单元格占位): ### 解决方案 ```xml <fo:table-row> <fo:table-cell> <fo:block> <xsl:choose> <!-- 检测空字符串或空白内容 --> <xsl:when test="normalize-space(NoInland) = ''">   <!-- 插入不换行空格 --> </xsl:when> <xsl:otherwise> <xsl:value-of select="NoInland"/> <!-- 正常显示内容 --> </xsl:otherwise> </xsl:choose> </fo:block> </fo:table-cell> </fo:table-row> ``` ### 关键说明 1. **`normalize-space()` 函数** - 自动去除首尾空白符,并将内部连续空白压缩为单个空格 - `test="normalize-space(NoInland) = ''"` 可检测以下情况: - 空字符串 `""` - 纯空格字符串 `" "` - NULL 值(XSLT 中视为空节点) 2. **` ` 实体** - Unicode 不换行空格(相当于 HTML 的 ` `) - 确保空白符不会被 FO 处理器忽略 - 替代方案:直接写空格字符(但某些处理器可能忽略纯空格) 3. **逻辑扩展** - 如需兼容 NULL 数据库值,可追加 `or not(NoInland)` 检测: ```xml <xsl:when test="normalize-space(NoInland)='' or not(NoInland)"> ``` ### 注意事项 - **保留布局**:空单元格可能导致表格错位,强制空格可维持结构完整性 - **性能优化**:若 `NoInland` 字段不可能含空格,可简化为 `test="NoInland = ''"` - **特殊需求**:若需区分 **空字符串** 和 **NULL**,需分开处理: ```xml <xsl:when test="NoInland = ''"> <!-- 显式空字符串 --> <xsl:when test="not(NoInland)"> <!-- 数据库 NULL --> ``` > ⚠️ 提示:实际效果取决于 FO 处理器(如 Apache FOP、RenderX),建议验证输出 PDF/PS 的渲染结果。
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值