我现在正在与交响乐团合作几个星期并掌握它,真的很喜欢所有的基本功能。
我有一个问题,因为我不太清楚如何解决这个问题: 我有一个关于我正在进行的项目的新闻/博客页面。有时文章很短很短。我想要做的是显示一定数量的段落,但是当找到x个字符时停止。我找到了计算字符串长度的方法,但我希望它能像这样工作。
<p>paragraph with 20 chars</p>
<p>paragraph with 300 chars</p>
<p>paragraph with 500 chars</p>
等
现在我想配置最多200个字符。第二段将超过金额,但我希望内容同时显示第一段和第二段。所以它实际上是320个字符(不包括html和空格)。
我希望我不要模糊,有人知道我应该把它放在哪里。 最好的选择是编辑我想的数据源,但它对我来说似乎不是一个干净的方法,尽管它应该稍微减轻负载。
有人想指出我正确的方向吗?
答案 0 :(得分:2)
如果我正确阅读了这个问题,你想输出最小段落,以便段落中字符的总字符数大于所需的字符数。
例如,如果您有20,30和40个字符的段落。停止19,你只吐出第一个,停止21,你输出第1和第2段(21 <20 + 30),任何停止数大于50,你输出所有三个。
如果这是正确的,以下输出将满足您的需要 - 如果您更改此行:
<xsl:if test="30 > string-length($prev)">
其中30变为所需的字符串长度。
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:template match="/">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="ps">
<h2>
<xsl:value-of select="./@name"/>
</h2>
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="p">
<xsl:variable name="prev">
<xsl:for-each select="preceding-sibling::node()">
<xsl:value-of select="."/>
</xsl:for-each>
</xsl:variable>
<xsl:if test="30 > string-length($prev)">
<xsl:copy-of select="."/>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
<pss>
<ps name="test1">
<p>paragraph with 20 chars</p>
<p>paragraph with 300 chars</p>
<p>paragraph with 500 chars</p>
</ps>
<ps name="test2">
<p>paragraph with 20 chars much greater characters</p>
<p>paragraph with 300 chars</p>
<p>paragraph with 500 chars</p>
</ps>
<ps name="test2">
<p>few chars</p>
<p>few chars</p>
<p>few chars</p>
</ps>
</pss>
<h2>test1</h2>
<div>
<p>paragraph with 20 chars</p>
<p>paragraph with 300 chars</p>
</div>
<h2>test2</h2>
<div>
<p>paragraph with 20 chars much greater characters</p>
</div>
<h2>test2</h2>
<div>
<p>few chars</p>
<p>few chars</p>
<p>few chars</p>
</div>
答案 1 :(得分:2)
对于狗屎和傻笑,我只是添加我必须做的事情,以实现我想要实现的目标:
<xsl:for-each select="body/p">
<xsl:variable name="prev">
<xsl:for-each select="preceding-sibling::node()">
<xsl:value-of select="."/>
</xsl:for-each>
</xsl:variable>
<xsl:if test="50 > string-length($prev)">
<xsl:copy-of select="."/>
</xsl:if>
</xsl:for-each>
它可能会帮助其他人寻找这个,所以我想我可以添加自己的答案。
答案 2 :(得分:2)
来自@stormtroopr的解决方案将起作用,但它具有O(n ^ 2)性能:如果段落数量翻倍,样式表所用的时间将增加4倍。更好的解决方案是使用递归。这很棘手,直到你掌握它,但它并不复杂。基本上你处理第一段作为参数传递最大长度:
<xsl:apply-templates select="p[1]">
<xsl:with-param name="length-so-far" select="0"/>
<xsl:with-param name="max-length" select="200"/>
</xsl:apply-templates>
然后每个段落首先输出自己,然后决定是否继续下一个:
<xsl:template match="p">
<xsl:param name="length-so-far"/>
<xsl:param name="max-length"/>
<xsl:if test="$length-so-far < $max-length">
<xsl:copy-of select="."/>
<xsl:apply-templates select="following-sibling::p[1]">
<xsl:with-param name="length-so-far" select="$length-so-far + string-length(.)"/>
<xsl:with-param name="max-length" select="$max-length"/>
</xsl:apply-templates>
</xsl:if>
</xsl:template>