gpt4 book ai didi

xml - xsl : transforming a list into a 2-D table

转载 作者:数据小太阳 更新时间:2023-10-29 01:49:51 25 4
gpt4 key购买 nike

假设我有这个 XML 节点:

<items>
<item>...<item>
<item>...<item>
<item>...<item>
<item>...<item>
<item>...<item>
...
</items>

哪里有 N item节点。

现在我想把它转换成一个有 4 列的 HTML 表格。 (例如,如果 N=12,则有 3 个完整行,如果 N=27,则有 7 行,最后有 3 个单元格)

我该怎么做呢?

我的直觉是这样做,其中 {{something}}是我不知道如何实现的:

<xsl:template match="items">
<table>
<xsl:call-template name="partition-items">
<xsl:with-param name="skip" select="0" />
</xsl:call-template>
</table>
</xsl:template>

<xsl:template name="partition-items">
<xsl:param name="skip" />
{{ if # of items in current node > $skip,
output a row,
and call partition-items($skip+4)
}}
<xsl:template />

我不知道如何实现的部分是

  • 如何为测试item 的# 创建谓词当前节点中的元素
  • 如何获得第 N 个 item当前节点中的元素

评论更新

How to pad the last row with empty <td /> elements so that each row contains exactly the wanted cells?

最佳答案

我。 XSLT 1.0 解决方案:

这可能是最短的解决方案之一,特别是不需要显式递归:

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:param name="pNumCols" select="4"/>

<xsl:template match="/*">
<table>
<xsl:apply-templates select="*[position() mod $pNumCols =1]"/>
</table>
</xsl:template>

<xsl:template match="item">
<tr>
<xsl:apply-templates mode="copy" select=
". | following-sibling::*[not(position() >= $pNumCols)]"/>
</tr>
</xsl:template>

<xsl:template match="item" mode="copy">
<td><xsl:value-of select="."/></td>
</xsl:template>
</xsl:stylesheet>

当此转换应用于以下 XML 文档时:

<items>
<item>1</item>
<item>2</item>
<item>3</item>
<item>4</item>
<item>5</item>
<item>6</item>
<item>7</item>
<item>8</item>
<item>9</item>
<item>10</item>
<item>11</item>
<item>12</item>
<item>13</item>
<item>14</item>
<item>15</item>
<item>16</item>
<item>17</item>
<item>18</item>
<item>19</item>
<item>20</item>
<item>21</item>
<item>22</item>
<item>23</item>
<item>24</item>
<item>25</item>
<item>26</item>
<item>27</item>
</items>

产生了想要的、正确的结果:

<table>
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
</tr>
<tr>
<td>5</td>
<td>6</td>
<td>7</td>
<td>8</td>
</tr>
<tr>
<td>9</td>
<td>10</td>
<td>11</td>
<td>12</td>
</tr>
<tr>
<td>13</td>
<td>14</td>
<td>15</td>
<td>16</td>
</tr>
<tr>
<td>17</td>
<td>18</td>
<td>19</td>
<td>20</td>
</tr>
<tr>
<td>21</td>
<td>22</td>
<td>23</td>
<td>24</td>
</tr>
<tr>
<td>25</td>
<td>26</td>
<td>27</td>
</tr>
</table>

解释:

  1. 每行所需的单元格数在外部/全局参数中指定 $pNumCols .

  2. 模板仅应用于顶部元素的此类子元素,其位置是新行的开始 -- 它们由表达式 $k * $pNumCols +1 生成,其中 $k 可以是任何整数。

  3. 处理每个行起始项的模板创建一行(tr 元素)并在其中以特殊模式应用模板 "copy" 对于 $pNumCols从自身开始。

  4. 匹配 item 的模板在模式 "copy"只需创建一个单元格(td 元素) 并在其中输出 item 的字符串值正在匹配的元素。

二。 XSLT 2.0 解决方案:

<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:param name="pNumCols" select="4"/>

<xsl:template match="items">
<table>
<xsl:for-each-group select="item"
group-by="(position()-1) idiv $pNumCols">
<tr>
<xsl:for-each select="current-group()">
<td>
<xsl:apply-templates/>
</td>
</xsl:for-each>
</tr>
</xsl:for-each-group>
</table>
</xsl:template>
</xsl:stylesheet>

应用于与之前相同的 XML 文档,此转换产生相同的正确结果。

解释:

  1. <xsl:for-each-group> 指令用于选择不同组的item元素,其中每个组包含必须在一行中表示的元素。

  2. 标准 XPath 2.0 运算符 idiv 用于此目的。

  3. XSLT 2.0 函数 current-group() 包含必须出现在当前行中的所有项目

关于xml - xsl : transforming a list into a 2-D table,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4846065/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com