使用 XSLT 将 XML 元素格式化为两个一组的 HTML
我有以下 XML 数据集(简化),其中可以有从零到无限的项目(通常有 2-10 个):
<item template="event_element">
<mytitle>This is the first title</mytitle>
<mydate>20110330T143004</mytitle>
<mydescription>This is the first description</mytitle>
<mylink>www.example.com</mytitle>
</item>
.
.
<item template="event_element">
<mytitle>This is the Tenth title</mytitle>
<mydate>20110330T143004</mytitle>
<mydescription>This is the tenth description</mytitle>
<mylink>www.example.com</mytitle>
</item>
我的最终结果应该是这样的,我可以得到几组项目(这将由 javascript 旋转):
<div class="body">
<div class="rel" id="arrangement">
// First set of items goes here
<div class="item">
<div class="itm">
<div class="in">
<p>
<a href="MY LINK" title="MY LINK DESCRIPTION">
<span>MY DATE</span>
<strong>MY FIRST TITLE</strong>
MY SHORT DESCRIPTION...
</a>
</p>
</div>
</div>
<div class="itm last">
<div class="in">
<p>
<a href="MY LINK" title="MY LINK DESCRIPTION">
<span>30. mar 2011</span>
<strong>MY SECOND TITLE</strong>
MY SHORT DESCRIPTION...
</a>
</p>
</div>
</div>
<div class="clr"></div>
</div>
// Second set of items goes here
<div class="item">
<div class="itm">
<div class="in">
<p>
<a href="MY LINK" title="MY LINK DESCRIPTION">
<span>MY DATE</span>
<strong>MY THIRD TITLE</strong>
MY SHORT DESCRIPTION...
</a>
</p>
</div>
</div>
<div class="itm last">
<div class="in">
<p>
<a href="MY LINK" title="MY LINK DESCRIPTION">
<span>30. mar 2011</span>
<strong>MY FORTH TITLE</strong>
MY SHORT DESCRIPTION...
</a>
</p>
</div>
</div>
<div class="clr"></div>
</div>
<div class="clr"></div>
</div>
我的问题是逐步浏览我的项目(甚至应该按日期描述排序)并将它们分成两组。
就像今天一样,我被迫对这样的集合进行硬编码($eventfolder、$totalevents 变量已预定义):
<pre><code><div class="body">
<div class="rel" id="arrangement">
<xsl:if test="$totalevents > 0">
<div class="item">
<xsl:for-each select="$eventfolder/item[@template='event_element' and position() > 0 and position() < 3]">
<xsl:choose>
<xsl:when test="position() < $eventsperpage">
<div class="itm">
<xsl:call-template name="renderEvent" />
</div>
</xsl:when>
<xsl:otherwise>
<div class="itm last">
<xsl:call-template name="renderEvent" />
</div>
<div class="clr"></div>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</div>
</xsl:if>
<xsl:if test="$totalevents > 2">
<div class="item">
<xsl:for-each select="$eventfolder/item[@template='event_element' and position() > 2 and position() < 5]">
<xsl:choose>
<xsl:when test="position() < $eventsperpage">
<div class="itm">
<xsl:call-template name="renderEvent" />
</div>
</xsl:when>
<xsl:otherwise>
<div class="itm last">
<xsl:call-template name="renderEvent" />
</div>
<div class="clr"></div>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</div>
</xsl:if>
<div class="clr"></div>
</div>
</div>
</code></pre>
renderElement 模板仅呈现内部事件 HTML。
但如果我想显示多于 2 个的集合,或者甚至在每个集合中显示更多的项目,那么这种方法就不太实用了... xslt 文件会很大并且不可读...
对我如何解决这个问题有任何帮助,因为我不知道如何插入 HTML 标签,因为 XSLT 编译器看不到它们被关闭 - 即。 (当 test="position() = 1
插入 html 开始标签,然后当 test="position() = X
关闭标签时)。
提前致谢
I have the following XML dataset (simplified), where I can have from zero to endless items (usually there will be 2-10):
<item template="event_element">
<mytitle>This is the first title</mytitle>
<mydate>20110330T143004</mytitle>
<mydescription>This is the first description</mytitle>
<mylink>www.example.com</mytitle>
</item>
.
.
<item template="event_element">
<mytitle>This is the Tenth title</mytitle>
<mydate>20110330T143004</mytitle>
<mydescription>This is the tenth description</mytitle>
<mylink>www.example.com</mytitle>
</item>
My end result should be like this, where I can end up with several sets of items (which will be rotated by javascript):
<div class="body">
<div class="rel" id="arrangement">
// First set of items goes here
<div class="item">
<div class="itm">
<div class="in">
<p>
<a href="MY LINK" title="MY LINK DESCRIPTION">
<span>MY DATE</span>
<strong>MY FIRST TITLE</strong>
MY SHORT DESCRIPTION...
</a>
</p>
</div>
</div>
<div class="itm last">
<div class="in">
<p>
<a href="MY LINK" title="MY LINK DESCRIPTION">
<span>30. mar 2011</span>
<strong>MY SECOND TITLE</strong>
MY SHORT DESCRIPTION...
</a>
</p>
</div>
</div>
<div class="clr"></div>
</div>
// Second set of items goes here
<div class="item">
<div class="itm">
<div class="in">
<p>
<a href="MY LINK" title="MY LINK DESCRIPTION">
<span>MY DATE</span>
<strong>MY THIRD TITLE</strong>
MY SHORT DESCRIPTION...
</a>
</p>
</div>
</div>
<div class="itm last">
<div class="in">
<p>
<a href="MY LINK" title="MY LINK DESCRIPTION">
<span>30. mar 2011</span>
<strong>MY FORTH TITLE</strong>
MY SHORT DESCRIPTION...
</a>
</p>
</div>
</div>
<div class="clr"></div>
</div>
<div class="clr"></div>
</div>
My problem is stepping through my items (that should even be sorted by the date desc) and grouping them in sets of two.
As it is today I have been forced to hardcode the sets like this (the $eventfolder, $totalevents variables have been predefined):
<pre><code><div class="body">
<div class="rel" id="arrangement">
<xsl:if test="$totalevents > 0">
<div class="item">
<xsl:for-each select="$eventfolder/item[@template='event_element' and position() > 0 and position() < 3]">
<xsl:choose>
<xsl:when test="position() < $eventsperpage">
<div class="itm">
<xsl:call-template name="renderEvent" />
</div>
</xsl:when>
<xsl:otherwise>
<div class="itm last">
<xsl:call-template name="renderEvent" />
</div>
<div class="clr"></div>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</div>
</xsl:if>
<xsl:if test="$totalevents > 2">
<div class="item">
<xsl:for-each select="$eventfolder/item[@template='event_element' and position() > 2 and position() < 5]">
<xsl:choose>
<xsl:when test="position() < $eventsperpage">
<div class="itm">
<xsl:call-template name="renderEvent" />
</div>
</xsl:when>
<xsl:otherwise>
<div class="itm last">
<xsl:call-template name="renderEvent" />
</div>
<div class="clr"></div>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</div>
</xsl:if>
<div class="clr"></div>
</div>
</div>
</code></pre>
The renderElement template simply renders the inside event HTML.
But that way is not very practical if I wanted to show more sets than 2 - or even show more items in each set... The xslt file would be big and unreadable...
Any help to how I can solve this problem, since I cant figure out how to insert HTML tags as the XSLT compiler cant see them being closed - ie. (when test="position() = 1
insert html start tag and then later when test="position() = X
close the tag).
Thanks in advance
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
在不涉及您的方法所引发的更大问题的情况下,在 XSLT 中,一次对包含 n 个元素的元素列表进行分组的方法是这样的:
...它将应用组模式模板到第一个、第 n+1 个、第 2n+ 个元素当前元素的第 1 个等子元素。组模式模板如下所示:
这将创建一个
group
元素,并在该元素内将模板应用于当前元素及其后续 n-1 个同级元素。最终效果是,只要 n 是正整数,上面的代码就会创建包含源树中 n 个连续元素的
group
元素。在您的示例中,您将创建一个div
而不是group
以及其他更改。Without getting into the larger issues raised by your approach, in XSLT the way to group a list of elements n elements at a time is this:
...which will apply the group-mode template to the first, n+1th, 2n+1th, etc. child elements of the current element. The group-mode template looks like this:
This creates a
group
element, and within that element, applies templates to the current element and its n-1 following siblings.The net effect is that as long as n is a positive integer, the above will create
group
elements containing n consecutive elements from the source tree. In your example, you'd create adiv
instead of agroup
, among other changes.关于:
您对问题的思考是错误的。XSLT 生成树,而不是标签。您创建元素,而不是元素的一半。
以下样式表:
应用对此输入:
产生以下输出:
通过修改
group
变量的值来更改每个组中包含的项目数。Regarding:
You're thinking about the problem wrong. XSLT generates trees, not tags. You create elements, not halves of elements.
The following stylesheet:
Applied to this input:
Produces the following output:
Change the number of items to include in each group by modifying the value of the
group
variable.你在使用类似的东西吗?
are you using something similar to this?