使用子位置在XSLT中创建网格

时间:2014-02-13 21:03:45

标签: twitter-bootstrap xslt

我正在尝试创建一个如下指定的网格:

<Node>
  <UI>Grid</UI>
  <Rows>3</Rows>
  <Cols>3</Cols>
  <Node>stuff</Node>
  <Node>stuff</Node>
  <Node>stuff</Node>
  ...
</Node>

我想使用Bootstrap,所以我有

<xsl:template match ="Node[UI[contains(., 'Grid')]]">
    <div class ="container-fluid">
        <xsl:apply-templates select="Node" mode="Grid"/>
    </div>

</xsl:template>

然后:

<xsl:template match ="=Node" mode="Grid">
    <div class ="col-lg-???">
        <xsl:apply-templates />
    </div>

</xsl:template>

在最后一部分,col-lg - ???应该以某种方式将节点的位置用作网格节点内的子节点来计算所需的标记,以便正确创建网格。最终,&lt; 3,3&gt;网格将有9个节点,我想自动订购它们:

grid

只需使用它们在网格节点内的位置即可。我知道我还需要考虑最终在容器内划船,也不确定。通常会推断出Cols Cols = Children/Rows

输出应该是这样的:

<div class = "container">
  <div class ="row">
    <div class = "col-lg-4" ></div>
    <div class = "col-lg-4" ></div>
    <div class = "col-lg-4" ></div>
  </div>
  <div class ="row">
    <div class = "col-lg-4" ></div>
    <div class = "col-lg-4" ></div>
    <div class = "col-lg-4" ></div>
  </div>
  <div class ="row">
    <div class = "col-lg-4" ></div>
    <div class = "col-lg-4" ></div>
    <div class = "col-lg-4" ></div>
  </div>
</div>

修改

这似乎可以完成工作,如果它是一行:

<div class ="col-lg-{12 div count(../Node)}">
     <xsl:apply-templates />
</div>

但不确定行部分。

EDIT2:

到目前为止我所拥有的:

<xsl:template match ="//Sub/Node">
    <xsl:if test="count(./preceding-sibling::*) mod (count(../Node) div ../../Rows/text()) = 0">
        <div class ="row"></div>
    </xsl:if>
    <div class ="col-lg-{12 div count(../Node)}">
        <xsl:apply-templates />
    </div>
    <xsl:if test="count(./preceding-sibling::*) mod (count(../Node) div ../../Rows/text()) = 1">
        <div class ="rowclose"></div>
    </xsl:if>
</xsl:template>

rowclose只是用于表示法,当我在上面的if语句中打开一个div并在第二个中关闭它时,它不喜欢它。我会尝试解决这个问题。结果:

<div class="container-fluid">
    <div class="row"></div>
        <div class="col-lg-3"></div>
        <div class="col-lg-3"></div>
    <div class="rowclose"></div>
    <div class="row"></div>
        <div class="col-lg-3"></div>
        <div class="col-lg-3"></div>
    <div class="rowclose"></div>
</div>

1 个答案:

答案 0 :(得分:1)

我不是100%清楚你要实现的是什么,但我认为你试图每行创建三个“节点”,将每一行包含在 div 元素中。

如果是这样,你应该开始做的是选择节点元素,它们将成为每一行中的第一个元素(其中 $ cols 是一个持有一行中的节点数量)

<xsl:apply-templates select="Node[position() mod $cols = 1]" mode="row"/>

(此处需要“行”模式,因为您最终会得到两个匹配节点的模板)

或者如果你想限制行数应该有多于你需要的节点,你可以这样做(“Position()”是上下文敏感的,并且与你刚刚选择的节点有关,不一定是他们的位置在树上)

<xsl:apply-templates select="Node[position() mod $cols = 1][position() &lt;= $rows]" mode="row"/>

然后你会在“行”模式中找到一个与之匹配的模板

                        

要选择行中的节点,请执行此操作

<xsl:apply-templates select="self::*|following-sibling::Node[position() &lt; $cols]" mode="cell"/>

然后你会为第二个模板匹配节点,你可以在这里输出带有类的div(其中 lg 是一个保存表达式的变量以避免它反复重新计算)

                        

试试这个XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   <xsl:output omit-xml-declaration="yes" indent="yes" />
   <xsl:variable name="cols" select="/*/Cols" />
   <xsl:variable name="rows" select="/*/Rows" />
   <xsl:variable name="lg" select="12 div number(/*/Cols)" />

   <xsl:template match="/*">
     <div class="container">
        <xsl:apply-templates select="Node[position() mod $cols = 1][position() &lt; $rows]" mode="row"/>
     </div>
   </xsl:template>

   <xsl:template match="Node" mode="row">
     <div class="row">
        <xsl:apply-templates select="self::*|following-sibling::Node[position() &lt;= $cols]" mode="cell"/>
     </div>
   </xsl:template>

   <xsl:template match="Node" mode="cell">
     <div class="col-lg-{$lg}">
        <xsl:apply-templates />
     </div>
   </xsl:template>
</xsl:stylesheet>
相关问题