使用子位置在 XSLT 中创建网格 [英] Use child position to create a grid in XSLT

查看:24
本文介绍了使用子位置在 XSLT 中创建网格的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

<节点><UI>网格</UI><行>3</行><Cols>3</Cols><节点>东西</节点><节点>东西</节点><节点>东西</节点>...</节点>

我想使用 Bootstrap,所以我有

<div class="容器流体"><xsl:apply-templates select="Node" mode="Grid"/>

</xsl:模板>

然后:

<div class="col-lg-???"><xsl:apply-templates/>

</xsl:模板>

在最后一部分,col-lg-???应该以某种方式使用节点的位置作为网格节点内的子节点来计算所需的标签,以便正确创建网格.最终,一个 <3,3> 网格将有 9 个节点,我想像这样自动对它们进行排序:

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

输出应该是这样的:

<div 类 =行"><div class = "col-lg-4" ></div><div class = "col-lg-4" ></div><div class = "col-lg-4" ></div>

<div 类 =行"><div class = "col-lg-4" ></div><div class = "col-lg-4" ></div><div class = "col-lg-4" ></div>

<div 类 =行"><div class = "col-lg-4" ></div><div class = "col-lg-4" ></div><div class = "col-lg-4" ></div>

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

<xsl:apply-templates/>

但不确定行部分.

到目前为止我所拥有的:

<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/>

<xsl:if test="count(./preceding-sibling::*) mod (count(../Node) div ../../Rows/text()) = 1"><div class="rowclose"></div></xsl:if></xsl:模板>

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

<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>

解决方案

我不是 100% 清楚您要实现的目标,但我认为您正在尝试为每行创建三个节点",将每一行封闭起来在 div 元素中.

如果是这样,您应该首先选择 Node 元素作为每行中的第一个元素(其中 $cols 是保存一行中的节点数)

(此处需要行"模式,因为您最终会得到两个与 Node 匹配的模板)

或者如果你想限制行数,如果节点数超过你需要的数量,你可以这样做(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"/>

然后您将有第二个模板匹配 Node 单元格,您可以在其中输出带有类的 div(其中 lg 是保存表达式的变量,以避免它反复被重新计算)

试试这个 XSLT

<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="容器"><xsl:apply-templates select="Node[position() mod $cols = 1][position() &lt; $rows]" mode="row"/>

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

</xsl:模板><xsl:template match="Node" mode="cell"><div class="col-lg-{$lg}"><xsl:apply-templates/>

</xsl:模板></xsl:stylesheet>

I'm trying to create a grid specified like this:

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

I want to use Bootstrap, so I have

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

</xsl:template>

And then:

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

</xsl:template>

In the last part, col-lg-??? should somehow use the node's position as a child inside the grid node to calculate the required tag so that the grid will be properly created. Eventually, a <3,3> grid will have 9 nodes and I want to order them automatically like this:

Just by using their position inside the grid node. I'm aware I would need to also consider rowing inside the container eventually, not sure about that either. Cols would typically be inferred by Cols = Children/Rows.

Output should be something like:

<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>

EDIT:

This seems to get the job done, if it were one line:

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

But not sure about the row part.

EDIT2:

What I have so far:

<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 is just for notation, it doesn't like it when I open a div in the upper if statement and close it in the second, it seems. I will try working that out. The result:

<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>

解决方案

I am not 100% clear what it is you are trying to achieve, but I think you are trying to create three "Nodes" per row, enclosing each row in a div element.

If so, what you should start off by doing is selecting the Node elements that will be the first element in each row (where $cols is a variable holding the number of nodes in a row)

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

(The "row" mode is needed here because you will end up with two templates that match Node)

Or if you wanted to limit the number of rows should there be more Nodes than you need, you could do this ("Position()" is context sensitive, and relates to the nodes you have just selected, not necessarily their position in the tree)

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

Then you would have a template that matches this, in "row" mode

And to select the nodes in the row, do this

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

Then you would have a second template matching Node for the cells, where you could output the div with the class (where lg is a variable holding your expression to avoid it repeatedly being recalculated)

Try this 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>

这篇关于使用子位置在 XSLT 中创建网格的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
其他开发最新文章
热门教程
热门工具
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆