通常情况下,我们在缩短/截断文本内容时,通常只是在特定字符索引处进行截断。这已经很复杂了,但我希望使用不同的方法截断生成使用可编辑内容div
)的HTML内容:
- 我会定义一个字符索引
N
,作为截断起始点的限制 - 算法将检查内容是否至少
N
个字符长(仅限文本;不计标签);如果不是,则返回整个内容 - 然后它将从
N-X
到N+X
字符位置(仅限文本)进行检查,并搜索块节点的结束位置;X
是预定义的偏移值,可能约为N/5
至N/4
; - 如果在此范围内有多个块节点结束,算法将选择距离限制索引
N
最近的节点。 - 如果此范围内没有块节点结束,则它将在同一范围内找到最接近的单词边界,并选择最接近
N
的索引并在该位置截断。 - 返回截断后的内容,其中包含有效的HTML(所有标签在末尾关闭)
我的可编辑内容生成的内容可能包括段落(带有换行符),预格式化代码块,块引用,有序和无序列表,标题,加粗和斜体(这是内联节点,不应计入截断过程)等。当然,最终实现将定义哪些元素可能是截断候选项。标题即使它们是块HTML元素也不会作为截断点计数,因为我们不想要孤立的头部。段落、列表单个项、整个有序和无序列表、块引用、预格式化块、空元素等都是良好的截断候选项。标题和所有内联块元素都不是。
例子
让我们以这个stackoverflow问题作为要截断的HTML内容的例子。让我们将截断限制设置为1000,偏移量设置为250字符(1/4)。
这个 DotNetFiddle 显示了这个问题的文字,同时在其中添加了限制标记(|MIN|
代表字符 750,|LIMIT|
代表字符 1000,|MAX|
代表字符 1250)。
如从示例中可以看出,接近字符 1000 的两个块节点之间的截断边界是 </OL>
和 P
(“我的 content-editable 生成的...”)。这意味着我的 HTML 应该在这两个标签之间被截断,从文本角度来看,结果应该是少于 1000 个字符长的内容,但保持截断的内容有意义,因为它不会在某些文本段中间截断。
我希望这解释清楚了这个算法应该如何工作相关的事情。
问题
我看到的第一个问题是我正在处理类似 HTML 的嵌套结构。我还要检测不同的元素(只有块元素而没有内联元素)。最后但并非不重要的是,我将只计算字符串中的某些字符,并忽略属于标签的字符。
可能的解决方案
- 我可以通过创建表示内容节点及其层次结构的对象树来手动解析我的内容。
- 我可以将 HTML 转换为更易于管理的 Markdown,然后简单地搜索最接近提供的索引
N
的换行符,并将其转换回 HTML。 - 使用类似 HTML Agility Pack 的工具替换我的 #1 解析,然后以某种方式使用 XPath 提取块节点并截断内容。
另一种想法
- 我相信我可以通过执行 #1 来实现,但感觉自己在重复发明轮子。
- 我不认为有任何 C# 库适用于 #2,因此我也应该手动进行 HTML 到 Markdown 的转换,或运行例如 pandoc 作为外部进程。
如何处理这种截断算法?我的头脑似乎太疲惫了,无法达成一致意见(或解决方案)。
//text()
。然后,每个节点还具有XPath属性,因此您可以从这些文本元素来回遍历树。这些文本元素的内容可以使用InnerHtml属性轻松更改。最后,HAP在输出HTML时会自动关闭未关闭的元素。 - Simon Mourier