xsl for-each:每 n 行添加代码块?

发布于 2024-09-24 19:26:53 字数 942 浏览 6 评论 0原文

我正在尝试将一些代表图像库的 xml 转换为 html 表。 (必须使用 html 而不是 css 来完成)。 如何使用 xsl 每六列左右添加行分隔符

我有这样的:

<xsl:for-each select="//email/gallery" >
<td>
    <img>
    <xsl:attribute name="src">
        <xsl:value-of select="gallery-image-location"/>
    </xsl:attribute>
    <xsl:attribute name="alt">
        <xsl:value-of select="gallery-image-alt"/>
    </xsl:attribute>
    </img>
</td>
<xsl:if test="????">
    </tr>
    <tr>
</xsl:if>
<xsl:for-each>

在 Javascript 中我会做类似的事情:

for (i=0; i<gallery.length; i++) {
    htm += '<td><img src="' +
    gallery[i].gallery-image-location +
    '" alt="'+ gallery[i].gallery-image-alt +'"></td>';

    if (i%6 == 5 && i != gallery.length-1) {
        htm += '</tr><tr>';
    }
}

I am trying to transform a bit of xml which represents an image gallery into an html table. (it must be done with html and not with css). How do I add the row break </tr><tr> every six or so columns with xsl?

I have this:

<xsl:for-each select="//email/gallery" >
<td>
    <img>
    <xsl:attribute name="src">
        <xsl:value-of select="gallery-image-location"/>
    </xsl:attribute>
    <xsl:attribute name="alt">
        <xsl:value-of select="gallery-image-alt"/>
    </xsl:attribute>
    </img>
</td>
<xsl:if test="????">
    </tr>
    <tr>
</xsl:if>
<xsl:for-each>

In Javascript I would do something like:

for (i=0; i<gallery.length; i++) {
    htm += '<td><img src="' +
    gallery[i].gallery-image-location +
    '" alt="'+ gallery[i].gallery-image-alt +'"></td>';

    if (i%6 == 5 && i != gallery.length-1) {
        htm += '</tr><tr>';
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

悲喜皆因你 2024-10-01 19:26:53

如何添加换行符
每六列左右有 xsl?

在 XSLT 中则不然!

XSLT 处理节点,而不是标签。

这是位置分组的 XSLT 方式

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

 <xsl:template match="gallery[position() mod 6 = 1]">
  <tr>
   <xsl:apply-templates mode="proc"
        select=".|following-sibling::gallery[not(position() > 5)]"
   />
  </tr>
 </xsl:template>

 <xsl:template match="gallery" mode="proc">
  <td>
    <img src="{gallery-image-location}" alt="{gallery-image-alt}"/>
  </td>
 </xsl:template>

 <xsl:template match="gallery[not(position() mod 6 = 1)]"/>
</xsl:stylesheet>

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

<email>
    <gallery>
        <gallery-image-location>http://server/picts/1</gallery-image-location>
        <gallery-image-alt>Description 1</gallery-image-alt>
    </gallery>
    <gallery>
        <gallery-image-location>http://server/picts/2</gallery-image-location>
        <gallery-image-alt>Description 2</gallery-image-alt>
    </gallery>
    <gallery>
        <gallery-image-location>http://server/picts/3</gallery-image-location>
        <gallery-image-alt>Description 3</gallery-image-alt>
    </gallery>
    <gallery>
        <gallery-image-location>http://server/picts/41</gallery-image-location>
        <gallery-image-alt>Description 4</gallery-image-alt>
    </gallery>
    <gallery>
        <gallery-image-location>http://server/picts/5</gallery-image-location>
        <gallery-image-alt>Description 5</gallery-image-alt>
    </gallery>
    <gallery>
        <gallery-image-location>http://server/picts/6</gallery-image-location>
        <gallery-image-alt>Description 6</gallery-image-alt>
    </gallery>
    <gallery>
        <gallery-image-location>http://server/picts/7</gallery-image-location>
        <gallery-image-alt>Description 7</gallery-image-alt>
    </gallery>
    <gallery>
        <gallery-image-location>http://server/picts/8</gallery-image-location>
        <gallery-image-alt>Description 8</gallery-image-alt>
    </gallery>
    <gallery>
        <gallery-image-location>http://server/picts/9</gallery-image-location>
        <gallery-image-alt>Description 9</gallery-image-alt>
    </gallery>
</email>

生成所需的正确结果

<tr>
    <td>
        <img src="http://server/picts/1" alt="Description 1"/>
    </td>
    <td>
        <img src="http://server/picts/2" alt="Description 2"/>
    </td>
    <td>
        <img src="http://server/picts/3" alt="Description 3"/>
    </td>
    <td>
        <img src="http://server/picts/41" alt="Description 4"/>
    </td>
    <td>
        <img src="http://server/picts/5" alt="Description 5"/>
    </td>
    <td>
        <img src="http://server/picts/6" alt="Description 6"/>
    </td>
</tr>
<tr>
    <td>
        <img src="http://server/picts/7" alt="Description 7"/>
    </td>
    <td>
        <img src="http://server/picts/8" alt="Description 8"/>
    </td>
    <td>
        <img src="http://server/picts/9" alt="Description 9"/>
    </td>
</tr>

How do I add the row break
every six or so columns with xsl?

In XSLT you don't!

XSLT processes nodes, not tags.

Here is the XSLT way of positional grouping:

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

 <xsl:template match="gallery[position() mod 6 = 1]">
  <tr>
   <xsl:apply-templates mode="proc"
        select=".|following-sibling::gallery[not(position() > 5)]"
   />
  </tr>
 </xsl:template>

 <xsl:template match="gallery" mode="proc">
  <td>
    <img src="{gallery-image-location}" alt="{gallery-image-alt}"/>
  </td>
 </xsl:template>

 <xsl:template match="gallery[not(position() mod 6 = 1)]"/>
</xsl:stylesheet>

when this transformation is applied on the following XML document:

<email>
    <gallery>
        <gallery-image-location>http://server/picts/1</gallery-image-location>
        <gallery-image-alt>Description 1</gallery-image-alt>
    </gallery>
    <gallery>
        <gallery-image-location>http://server/picts/2</gallery-image-location>
        <gallery-image-alt>Description 2</gallery-image-alt>
    </gallery>
    <gallery>
        <gallery-image-location>http://server/picts/3</gallery-image-location>
        <gallery-image-alt>Description 3</gallery-image-alt>
    </gallery>
    <gallery>
        <gallery-image-location>http://server/picts/41</gallery-image-location>
        <gallery-image-alt>Description 4</gallery-image-alt>
    </gallery>
    <gallery>
        <gallery-image-location>http://server/picts/5</gallery-image-location>
        <gallery-image-alt>Description 5</gallery-image-alt>
    </gallery>
    <gallery>
        <gallery-image-location>http://server/picts/6</gallery-image-location>
        <gallery-image-alt>Description 6</gallery-image-alt>
    </gallery>
    <gallery>
        <gallery-image-location>http://server/picts/7</gallery-image-location>
        <gallery-image-alt>Description 7</gallery-image-alt>
    </gallery>
    <gallery>
        <gallery-image-location>http://server/picts/8</gallery-image-location>
        <gallery-image-alt>Description 8</gallery-image-alt>
    </gallery>
    <gallery>
        <gallery-image-location>http://server/picts/9</gallery-image-location>
        <gallery-image-alt>Description 9</gallery-image-alt>
    </gallery>
</email>

the wanted, correct result is produced:

<tr>
    <td>
        <img src="http://server/picts/1" alt="Description 1"/>
    </td>
    <td>
        <img src="http://server/picts/2" alt="Description 2"/>
    </td>
    <td>
        <img src="http://server/picts/3" alt="Description 3"/>
    </td>
    <td>
        <img src="http://server/picts/41" alt="Description 4"/>
    </td>
    <td>
        <img src="http://server/picts/5" alt="Description 5"/>
    </td>
    <td>
        <img src="http://server/picts/6" alt="Description 6"/>
    </td>
</tr>
<tr>
    <td>
        <img src="http://server/picts/7" alt="Description 7"/>
    </td>
    <td>
        <img src="http://server/picts/8" alt="Description 8"/>
    </td>
    <td>
        <img src="http://server/picts/9" alt="Description 9"/>
    </td>
</tr>
魂牵梦绕锁你心扉 2024-10-01 19:26:53

如果您使用的是 XSLT 2

<xsl:stylesheet version="2.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

 <xsl:template match="email">
   <xsl:for-each-group select="gallery" group-by="(position() - 1) idiv 6">
     <tr>
       <xsl:apply-templates select="current-group()"/>
     </tr>
   </xsl:for-each-group>
 </xsl:template>

 <xsl:template match="gallery">
  <td>
    <img src="{gallery-image-location}" alt="{gallery-image-alt}"/>
  </td>
 </xsl:template>

</xsl:stylesheet>

If you are using XSLT 2

<xsl:stylesheet version="2.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

 <xsl:template match="email">
   <xsl:for-each-group select="gallery" group-by="(position() - 1) idiv 6">
     <tr>
       <xsl:apply-templates select="current-group()"/>
     </tr>
   </xsl:for-each-group>
 </xsl:template>

 <xsl:template match="gallery">
  <td>
    <img src="{gallery-image-location}" alt="{gallery-image-alt}"/>
  </td>
 </xsl:template>

</xsl:stylesheet>
小猫一只 2024-10-01 19:26:53

首先,假设您使用的是 XML 或 HTML 的输出格式,我认为您不能像 段那样放置不匹配的标签。 XSL(在这些模式下)不仅仅像使用 Javascript 那样生成字符串输出。 (不过我可能是错的。)

你在那里所做的事情与分页密切相关;您可能会查看分页脚本。

这是我的一个(未经测试的)建议:

<!-- For every sixth item, starting with the first... -->
<xsl:for-each select="//email/gallery[position() mod 6 = 1]">
  <tr>
     <!-- Get that item's position... -->
     <xsl:variable name="thisPos" select="position()" />

     <!-- and select the six (or less) items starting with that position. -->
     <xsl:for-each select="//email/gallery[position() >= $thisPos and position() < $thisPos + 6]">
       <td><img>
        <xsl:attribute name="src">
          <xsl:value-of select="gallery-image-location"/>
        </xsl:attribute>
        <xsl:attribute name="alt">
          <xsl:value-of select="gallery-image-alt"/>
        </xsl:attribute>
       </img></td>
     </xsl:for-each>
  </tr>
</xsl:for-each>

哦,还有 IIRC,循环的内部也可以缩短一点:

<td><img src="{gallery-image-location}" alt="{gallery-image-alt}" /></td>

这些花括号将帮助您在长脚本上保持理智。

First, assuming that you are using an output format of XML or HTML, I don't think you can place unmatched tags as your are with the </tr><tr> segment. XSL (in these modes) doesn't just produce string output the way you would with your Javascript. (I could be wrong about this though.)

What you're doing there is closely related to paging; you might look at paging scripts.

Here's an (untested) suggestion from me:

<!-- For every sixth item, starting with the first... -->
<xsl:for-each select="//email/gallery[position() mod 6 = 1]">
  <tr>
     <!-- Get that item's position... -->
     <xsl:variable name="thisPos" select="position()" />

     <!-- and select the six (or less) items starting with that position. -->
     <xsl:for-each select="//email/gallery[position() >= $thisPos and position() < $thisPos + 6]">
       <td><img>
        <xsl:attribute name="src">
          <xsl:value-of select="gallery-image-location"/>
        </xsl:attribute>
        <xsl:attribute name="alt">
          <xsl:value-of select="gallery-image-alt"/>
        </xsl:attribute>
       </img></td>
     </xsl:for-each>
  </tr>
</xsl:for-each>

Oh, and IIRC, the interior of the loop can be shortened a little bit too:

<td><img src="{gallery-image-location}" alt="{gallery-image-alt}" /></td>

Those curly braces will help save your sanity on long scripts.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文