正如我在评论中已经提到的,如果要缩短的文本在子树的节点之间拆分,那么这会变得复杂。这很复杂,因为 - 至少从概念上讲 - XSLT 并行处理树的分支,并且无法将信息从一个分支传递到下一个分支,就像您在执行循环时那样。
您可以在这里采取两种可能的方法:
- 强制样式表按顺序处理节点;
- 让每个文本节点按文档顺序计算在当前分支之前的并行分支中发生了什么。
第二种选择似乎更容易,尽管它非常低效。这是一个通用示例:
XML
在本文档中,我插入了 a§
作为每个项目正文的第 100 个字符。
<feed>
<item>
<title>Declaration</title>
<body>
<para>When in the Course of human events, it becomes necessary for one people to <bold>dissolve the political b§ands which have connected them with another</bold>, and to assume among the powers of the earth, the separate and equal station to which the Laws of Nature and of Nature's God entitle them, a decent respect to the opinions of mankind requires that they should declare the causes which impel them to the separation.</para>
<para>We hold these truths to be self-evident, that all men are created equal, that they are endowed by their Creator with certain unalienable Rights, that among these are Life, Liberty and the pursuit of Happiness.</para>
</body>
</item>
<item>
<title>Lorem Isum</title>
<body>
<para>Lorem ipsum dolor sit amet consectetuer adipiscing elit. <bold>Nam interdum ante quis <italic>erat pellentesque e§lementum.</italic> Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus.</bold> Ut molestie quam sit amet ligula.</para>
<para>In enim. Duis dapibus hendrerit quam. Donec hendrerit lectus vel nunc. Vestibulum sit amet pede nec neque dignissim vehicula.</para>
<para>Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos hymenaeos. Phasellus eget ante. Quisque risus leo, dictum sit amet, nonummy sit amet, consectetuer ut, mi.</para>
</body>
</item>
<item>
<title>Subject</title>
<body>
<para>Subject to change without notice.</para>
<para>Not responsible for direct, indirect, incidental or consequential §damages resulting from any defect, error or failure to perform.</para>
<para>May be too intense for some viewers.</para>
</body>
</item>
</feed>
XSLT 2.0
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" omit-xml-declaration="yes" version="1.0" encoding="utf-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:param name="limit" select="100"/>
<xsl:template match="feed">
<body>
<xsl:apply-templates/>
</body>
</xsl:template>
<xsl:template match="item">
<h3><xsl:value-of select="title"/></h3>
<xsl:apply-templates select="body"/>
<hr/>
</xsl:template>
<xsl:template match="body">
<p>
<xsl:apply-templates mode="summary"/>
</p>
</xsl:template>
<xsl:template match="bold" mode="summary">
<b>
<xsl:apply-templates mode="summary"/>
</b>
</xsl:template>
<xsl:template match="italic" mode="summary">
<i>
<xsl:apply-templates mode="summary"/>
</i>
</xsl:template>
<xsl:template match="text()" mode="summary">
<xsl:variable name="text-before">
<xsl:value-of select="ancestor::body//text()[current() >> .]" separator=""/>
</xsl:variable>
<xsl:variable name="used" select="string-length($text-before)" />
<xsl:if test="$used lt $limit">
<xsl:value-of select="substring(., 1, $limit - $used)"/>
<xsl:if test="string-length(.) + $used ge $limit">
<xsl:text>...</xsl:text>
</xsl:if>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
结果
<body>
<h3>Declaration</h3>
<p>When in the Course of human events, it becomes necessary for one people to <b>dissolve the political bß...</b>
</p>
<hr/>
<h3>Lorem Isum</h3>
<p>Lorem ipsum dolor sit amet consectetuer adipiscing elit. <b>Nam interdum ante quis <i>erat pellentesque e§...</i>
</b>
</p>
<hr/>
<h3>Subject</h3>
<p>Subject to change without notice.Not responsible for direct, indirect, incidental or consequential ß...</p>
<hr/>
</body>
渲染

如您所见,每个项目恰好在 100 个字符后被切断,而内部层次结构被保留,每种类型的节点都可以单独处理。
注意:
在我写完这个之后,我去看看你链接到的另一个问题。那里接受的答案与此非常相似,尽管我相信我的答案更简单一些,并且它分别处理每个项目。