4

提前致歉——这里是新手,在阅读了这里的几乎所有 XSLT 线程后都在苦苦挣扎。所以我迫切需要几种阿司匹林和你的指导!!

我有三个需要使用 xslt 1.0 版处理的传入参数/变量。

<!-- Variables in the XSL -->
<xsl:variable name="tw">125</xsl:variable>
<xsl:variable name="rows">4</xsl:variable>
<xsl:variable name="cols">6</xsl:variable>

我想在 HTML 的“背景位置”中得到计算值(像素),如下所示: -

<div style="background-position:-0px -0px;"><img src="images/thumbs/1.jpg" alt="one" /></div>
<div style="background-position:-125px -0px;"><img src="images/thumbs/2.jpg" alt="two" /></div>
<div style="background-position:-250px -0px;"><img src="images/thumbs/3.jpg" alt="three" /></div>
<div style="background-position:-375px -0px;"><img src="images/thumbs/4.jpg" alt="four" /></div>
<div style="background-position:-500px -0px;"><img src="images/thumbs/5.jpg" alt="five" /></div>
<div style="background-position:-625px -0px;"><img src="images/thumbs/6.jpg" alt="six" /></div>

<div style="background-position:-0px -125px;"><img src="images/thumbs/7.jpg" alt="seven" /></div>
<div style="background-position:-125px -125px;"><img src="images/thumbs/8.jpg" alt="eight" /></div>
<div style="background-position:-250px -125px;"><img src="images/thumbs/9.jpg" alt="nine" /></div>
<div style="background-position:-375px -125px;"><img src="images/thumbs/10.jpg" alt="ten" /></div>
<div style="background-position:-500px -125px;"><img src="images/thumbs/11.jpg" alt="11" /></div>
<div style="background-position:-625px -125px;"><img src="MIB/images/thumbs/12.jpg" alt="12" /></div>

<div style="background-position:-0px -250px;"><img src="images/thumbs/13.jpg" alt="13" /></div>
<div style="background-position:-125px -250px;"><img src="/mages/thumbs/14.jpg" alt="14" /></div>
<div style="background-position:-250px -250px;"><img src="images/thumbs/15.jpg" alt="15" /></div>
<div style="background-position:-375px -250px;"><img src="images/thumbs/16.jpg" alt="16" /></div>
<div style="background-position:-500px -250px;"><img src="images/thumbs/17.jpg" alt="17" /></div>
<div style="background-position:-625px -250px;"><img src="images/thumbs/18.jpg" alt="18" /></div>

<div style="background-position:-0px -375px;"><img src="images/thumbs/19.jpg" alt="19" /></div>
<div style="background-position:-125px -375px;"><img src="images/thumbs/20.jpg" alt="20" /></div>
<div style="background-position:-250px -375px;"><img src="images/thumbs/21.jpg" alt="21" /></div>
<div style="background-position:-375px -375px;"><img src="images/thumbs/22.jpg" alt="22" /></div>
<div style="background-position:-500px -375px;"><img src="images/thumbs/23.jpg" alt="23" /></div>
<div style="background-position:-625px -375px;"><img src="images/thumbs/24.jpg" alt="24" /></div>

我意识到我需要循环(不知何故)并保持计数(不知何故)并且已经看到了许多循环和计数示例,我希望这个过程是直截了当的,但后来我读到了position()很多number其他的东西,我的头脑在旋转。我不知道如何或在何处定位for-each语句中的计数循环,或者即使 afor-each是最佳解决方案。我的微弱尝试都没有产生格式良好的 XSL,因此您可以看到我没有快速获得任何地方。

所以这里希望这里的一位大师可以帮助我开始这个过程并帮助我理解 xslt。

图像数据来自 XML 文件,我能够毫无问题地处理 img src 和 alt,所以问题只是像素计算、循环、计数等

<xsl:for-each select="DATASET/ITEM">
<div style="background-position:-{rowpos}px -{colpos}px;"><img src="{thumbnailimage}" alt="{imagealttext}" /></div>
</xsl:for-each>
<!-- rowpos and colpos are the calculated values that are generated from whatever loop and count process is used -->

所以为了澄清:

计算。有 3 个变量会产生 6 个计算值。tw=125。宽度用于背景位置,因此根据行/列计算值如示例中所示 - 例如 tw-tw、tw、tw*2、tw*3、tw*4 和 tw*5(总共6 次计算)。行数和列数使用计算的像素值确定每个缩略图的定位方式和位置 - 在上述情况下为 0px、-125px、-250px、-375px、-500px 和 -675px。

计算的进一步扩展:- 行和列的位置由缩略图的宽度决定。每个缩略图的位置由行数和列数决定。具有 150px 宽的缩略图的 3 行 x 3 列网格将需要 9 个缩略图,因此需要 9 组 px 值,但只需要 2 个唯一计算,例如 tw*2 和 tw*3,如下所示:-

<div style="background-position: -0px -0px;" /><img src="image 1.jpg" alt="Alt text 1" /></div>
<div style="background-position: -125px -0px;" /><img src="image 2.jpg" alt="Alt text 2" /></div>
<div style="background-position: -250px -0px;" /><img src="image 3.jpg" alt="Alt text 3" /></div>
<div style="background-position: -375px -0px;" /><img src="image 4.jpg" alt="Alt text 4" /></div>
<div style="background-position: -500px -0px;" /><img src="image 5.jpg" alt="Alt text 5" /></div>
<div style="background-position: -0px -125px;" /><img src="image 6.jpg" alt="Alt text 6" /></div>
<div style="background-position: -125px -125px;" /><img src="image 7.jpg" alt="Alt text 7" /></div>
<div style="background-position: -250px -125px;" /><img src="image 8.jpg" alt="Alt text 8" /></div>
<div style="background-position: -375px -125px;" /><img src="image 9.jpg" alt="Alt text 9" /></div>
<div style="background-position: -500px -125px;" /><img src="image 10.jpg" alt="Alt text 10" /></div>
<div style="background-position: -0px -250px;" /><img src="image 11.jpg" alt="Alt text 11" /></div>
<div style="background-position: -125px -250px;" /><img src="image 12.jpg" alt="Alt text 12" /></div>
<div style="background-position: -250px -250px;" /><img src="image 13.jpg" alt="Alt text 13" /></div>
<div style="background-position: -375px -250px;" /><img src="image 14.jpg" alt="Alt text 14" /></div>
<div style="background-position: -500px -250px;" /><img src="image 15.jpg" alt="Alt text 15" /></div>
<div style="background-position: -0px -375px;" /><img src="image 16.jpg" alt="Alt text 16" /></div>
<div style="background-position: -125px -375px;" /><img src="image 17.jpg" alt="Alt text 17" /></div>
<div style="background-position: -250px -375px;" /><img src="image 18.jpg" alt="Alt text 18" /></div>
<div style="background-position: -375px -375px;" /><img src="image 19.jpg" alt="Alt text 19" /></div>
<div style="background-position: -500px -375px;" /><img src="image 20.jpg" alt="Alt text 20" /></div>

XML 文件图像 src 和 alt 文本来自 XML 文件:-

<DATASET>
<ITEM>
   <THUMBNAILIMAGE>image1.jpg</THUMBNAILIMAGE>
   <IMAGEALTTEXT>Alt text 1</IMAGEALTTEXT>
</ITEM>
<ITEM>
   <THUMBNAILIMAGE>image2.jpg</THUMBNAILIMAGE>
   <IMAGEALTTEXT>Alt text 2</IMAGEALTTEXT>
</ITEM>
......
<ITEM>
   <THUMBNAILIMAGE>image20.jpg</THUMBNAILIMAGE>
   <IMAGEALTTEXT>Alt text 20</IMAGEALTTEXT>
</ITEM>
</DATASET>
4

3 回答 3

3

我认为这可以使用下面的代码(XSLT 1.0)来完成。以下转换应与任何 XML 文件一起使用。

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

<xsl:output indent="yes" />

<xsl:variable name="TW">125</xsl:variable>
<xsl:variable name="ROWS">4</xsl:variable>
<xsl:variable name="COLS">6</xsl:variable>
<xsl:variable name="TOTAL"><xsl:value-of select="$ROWS * $COLS"/></xsl:variable>

<xsl:template match="/">
    <xsl:call-template name="iterate_rows" />
</xsl:template>

<xsl:template name="iterate_rows">
    <xsl:param name="num">0</xsl:param> 

    <xsl:if test="not($num = $ROWS)">
        <xsl:call-template name="iterate_cols">
            <xsl:with-param name="rows" select="$num"/>
        </xsl:call-template>

        <xsl:call-template name="iterate_rows">
            <xsl:with-param name="num" select="$num + 1"/>
        </xsl:call-template>
    </xsl:if>
</xsl:template>

<xsl:template name="iterate_cols">
    <xsl:param name="num">0</xsl:param> 
    <xsl:param name="rows" />

    <xsl:if test="not($num = $COLS)">
        <xsl:element name="div">
            <xsl:attribute name="style" ><xsl:value-of select="concat('background-position:-', $TW*$num, 'px -', $TW*$rows, 'px;')" /></xsl:attribute>

            <xsl:variable name="number" select="$rows*$COLS + $num + 1" />

            <xsl:element name="img">
                <xsl:attribute name="src">
                    <xsl:value-of select="concat('images/thumbs/', $number, '.jpg')"/>
                </xsl:attribute>
                <xsl:attribute name="alt">
                    <xsl:value-of select="$number"/>
                </xsl:attribute>
            </xsl:element>

        </xsl:element>

        <xsl:call-template name="iterate_cols">
            <xsl:with-param name="num" select="$num + 1"/>
            <xsl:with-param name="rows" select="$rows" />
        </xsl:call-template>
    </xsl:if>
</xsl:template>

</xsl:stylesheet>

编辑:

在 XSLT 中,不可能构造类似于 C++ 或 Java 中的循环,因为不可能更改变量的值(因此不可能有计数器)。但是可以用重复来代替迭代。

在我的解决方案中,我定义了两个经常调用的模板——第一个是 named iterate_rows,而第二个是iterate_cols. 整个“程序”的入口点是:

<xsl:template match="/">
    <xsl:call-template name="iterate_rows" />
</xsl:template>

这首先被调用。命名模板iterate_rows有一个参数num,它的默认值设置为 0。重要的是<xsl:if ...>检查我们是否已经到达循环末尾的条件(在这种情况下,它的值是$ROWS)。在条件块内部,我们有两个调用:一个执行iterate_cols模板,第二个是对iterate_rows模板本身的调用(注意:我们用递增的参数调用它num)。第二个模板以类似的方式工作。希望这可以帮助。

于 2012-06-02T14:57:26.313 回答
1

在 XSLT 2.0 中,这很简单:类似于:

<xsl:for-each select="1 to $rows">
  <xsl:variable name="row" select="position()"/>
  <xsl:for-each select="1 to $columns">
     <xsl:variable name="column" select="position()"/>
     <div style="background-position: -{$row*$tw}px -{$column*$tw}px"/>
  </
</

在 1.0 中,您没有使用select="1 to $rows",但流行的解决方法是使用select="(//*)[position() &lt;= $rows]",只要源文档中至少有 $rows 元素,它就可以工作。您实际上对选择的节点并不感兴趣,只对它们中有多少感兴趣,这决定了您执行循环的次数。

于 2012-06-02T18:03:03.900 回答
0

这是一个完整、更短、更简单(只有一个递归模板)的递归 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="pTw" select="125"/>
     <xsl:param name="pNumRows" select="4"/>
     <xsl:param name="pNumCols" select="5"/>

     <xsl:variable name="vImageItems" select="/*/*"/>

     <xsl:template match="/">
      <xsl:call-template name="generateDiv"/>
     </xsl:template>

     <xsl:template name="generateDiv">
      <xsl:param name="pRow" select="1"/>
      <xsl:param name="pCol" select="1"/>

      <xsl:if test="not($pRow > $pNumRows)">
        <xsl:variable name="vImageItem" select=
        "$vImageItems[($pRow -1)*$pNumCols + $pCol]"/>

        <div style="background-position: -{($pCol -1)*$pTw}px -{($pRow -1)*$pTw}px;">
          <img src="{$vImageItem/THUMBNAILIMAGE}"
               alt="{$vImageItem/IMAGEALTTEXT}" />
        </div>

        <xsl:variable name="vnewCol">
         <xsl:choose>
          <xsl:when test="$pCol = $pNumCols">1</xsl:when>
          <xsl:otherwise><xsl:value-of select="$pCol+1"/></xsl:otherwise>
         </xsl:choose>
        </xsl:variable>

        <xsl:variable name="vnewRow">
          <xsl:choose>
            <xsl:when test="$vnewCol = 1"><xsl:value-of select="$pRow+1"/></xsl:when>
            <xsl:otherwise><xsl:value-of select="$pRow"/></xsl:otherwise>
          </xsl:choose>
        </xsl:variable>

        <xsl:call-template name="generateDiv">
         <xsl:with-param name="pRow" select="$vnewRow"/>
         <xsl:with-param name="pCol" select="$vnewCol"/>
        </xsl:call-template>
      </xsl:if>
     </xsl:template>
</xsl:stylesheet>

当此转换应用于提供的 XML 文档时

<DATASET>
    <ITEM>
        <THUMBNAILIMAGE>image1.jpg</THUMBNAILIMAGE>
        <IMAGEALTTEXT>Alt text 1</IMAGEALTTEXT>
    </ITEM>
    <ITEM>
        <THUMBNAILIMAGE>image2.jpg</THUMBNAILIMAGE>
        <IMAGEALTTEXT>Alt text 2</IMAGEALTTEXT>
    </ITEM>
    <ITEM>
        <THUMBNAILIMAGE>image3.jpg</THUMBNAILIMAGE>
        <IMAGEALTTEXT>Alt text 3</IMAGEALTTEXT>
    </ITEM>
    <ITEM>
        <THUMBNAILIMAGE>image4.jpg</THUMBNAILIMAGE>
        <IMAGEALTTEXT>Alt text 4</IMAGEALTTEXT>
    </ITEM>
    <ITEM>
        <THUMBNAILIMAGE>image5.jpg</THUMBNAILIMAGE>
        <IMAGEALTTEXT>Alt text 5</IMAGEALTTEXT>
    </ITEM>
    <ITEM>
        <THUMBNAILIMAGE>image6.jpg</THUMBNAILIMAGE>
        <IMAGEALTTEXT>Alt text 6</IMAGEALTTEXT>
    </ITEM>
    <ITEM>
        <THUMBNAILIMAGE>image7.jpg</THUMBNAILIMAGE>
        <IMAGEALTTEXT>Alt text 7</IMAGEALTTEXT>
    </ITEM>
    <ITEM>
        <THUMBNAILIMAGE>image8.jpg</THUMBNAILIMAGE>
        <IMAGEALTTEXT>Alt text 8</IMAGEALTTEXT>
    </ITEM>
    <ITEM>
        <THUMBNAILIMAGE>image9.jpg</THUMBNAILIMAGE>
        <IMAGEALTTEXT>Alt text 9</IMAGEALTTEXT>
    </ITEM>
    <ITEM>
        <THUMBNAILIMAGE>image10.jpg</THUMBNAILIMAGE>
        <IMAGEALTTEXT>Alt text 10</IMAGEALTTEXT>
    </ITEM>
    <ITEM>
        <THUMBNAILIMAGE>image11.jpg</THUMBNAILIMAGE>
        <IMAGEALTTEXT>Alt text 11</IMAGEALTTEXT>
    </ITEM>
    <ITEM>
        <THUMBNAILIMAGE>image12.jpg</THUMBNAILIMAGE>
        <IMAGEALTTEXT>Alt text 12</IMAGEALTTEXT>
    </ITEM>
    <ITEM>
        <THUMBNAILIMAGE>image13.jpg</THUMBNAILIMAGE>
        <IMAGEALTTEXT>Alt text 13</IMAGEALTTEXT>
    </ITEM>
    <ITEM>
        <THUMBNAILIMAGE>image14.jpg</THUMBNAILIMAGE>
        <IMAGEALTTEXT>Alt text 14</IMAGEALTTEXT>
    </ITEM>
    <ITEM>
        <THUMBNAILIMAGE>image15.jpg</THUMBNAILIMAGE>
        <IMAGEALTTEXT>Alt text 15</IMAGEALTTEXT>
    </ITEM>
    <ITEM>
        <THUMBNAILIMAGE>image16.jpg</THUMBNAILIMAGE>
        <IMAGEALTTEXT>Alt text 16</IMAGEALTTEXT>
    </ITEM>
    <ITEM>
        <THUMBNAILIMAGE>image17.jpg</THUMBNAILIMAGE>
        <IMAGEALTTEXT>Alt text 17</IMAGEALTTEXT>
    </ITEM>
    <ITEM>
        <THUMBNAILIMAGE>image18.jpg</THUMBNAILIMAGE>
        <IMAGEALTTEXT>Alt text 18</IMAGEALTTEXT>
    </ITEM>
    <ITEM>
        <THUMBNAILIMAGE>image19.jpg</THUMBNAILIMAGE>
        <IMAGEALTTEXT>Alt text 19</IMAGEALTTEXT>
    </ITEM>
    <ITEM>
        <THUMBNAILIMAGE>image20.jpg</THUMBNAILIMAGE>
        <IMAGEALTTEXT>Alt text 20</IMAGEALTTEXT>
    </ITEM>
</DATASET>

产生了想要的正确结果:

<div style="background-position: -0px -0px;">
   <img src="image1.jpg" alt="Alt text 1"/>
</div>
<div style="background-position: -125px -0px;">
   <img src="image2.jpg" alt="Alt text 2"/>
</div>
<div style="background-position: -250px -0px;">
   <img src="image3.jpg" alt="Alt text 3"/>
</div>
<div style="background-position: -375px -0px;">
   <img src="image4.jpg" alt="Alt text 4"/>
</div>
<div style="background-position: -500px -0px;">
   <img src="image5.jpg" alt="Alt text 5"/>
</div>
<div style="background-position: -0px -125px;">
   <img src="image6.jpg" alt="Alt text 6"/>
</div>
<div style="background-position: -125px -125px;">
   <img src="image7.jpg" alt="Alt text 7"/>
</div>
<div style="background-position: -250px -125px;">
   <img src="image8.jpg" alt="Alt text 8"/>
</div>
<div style="background-position: -375px -125px;">
   <img src="image9.jpg" alt="Alt text 9"/>
</div>
<div style="background-position: -500px -125px;">
   <img src="image10.jpg" alt="Alt text 10"/>
</div>
<div style="background-position: -0px -250px;">
   <img src="image11.jpg" alt="Alt text 11"/>
</div>
<div style="background-position: -125px -250px;">
   <img src="image12.jpg" alt="Alt text 12"/>
</div>
<div style="background-position: -250px -250px;">
   <img src="image13.jpg" alt="Alt text 13"/>
</div>
<div style="background-position: -375px -250px;">
   <img src="image14.jpg" alt="Alt text 14"/>
</div>
<div style="background-position: -500px -250px;">
   <img src="image15.jpg" alt="Alt text 15"/>
</div>
<div style="background-position: -0px -375px;">
   <img src="image16.jpg" alt="Alt text 16"/>
</div>
<div style="background-position: -125px -375px;">
   <img src="image17.jpg" alt="Alt text 17"/>
</div>
<div style="background-position: -250px -375px;">
   <img src="image18.jpg" alt="Alt text 18"/>
</div>
<div style="background-position: -375px -375px;">
   <img src="image19.jpg" alt="Alt text 19"/>
</div>
<div style="background-position: -500px -375px;">
   <img src="image20.jpg" alt="Alt text 20"/>
</div>

说明

  1. 这是一个递归解决方案。如果保证迭代次数不超过可用节点的总数(在源 XML 文档和 XSLT 样式表中),则可以使用非递归解决方案(又名Piez 方法)。

  2. 停止条件:当前行号值变得大于参数指定的行数($pRow > $pNumRows)。

  3. 操作:生成必要的新div元素,然后获取用于执行下一个操作的列号和行号的值。

于 2012-06-02T20:10:27.783 回答