如何使用Java缩写HTML?

2022-09-02 10:53:07

用户在表单中以 HTML 格式输入文本,例如:

<p>this is my <strong>blog</strong> post, 
very <i>long</i> and written in <b>HTML</b></p>

我希望能够只输出字符串的一部分(例如前20个字符),而不会破坏用户输入的HTML结构。在这种情况下:

<p>this is my <strong>blog</strong> post, very <i>l</i>...</p>

它呈现为

this is my <strong>blog</strong> post, very <i>lo</i>...

有没有一个Java库可以做到这一点,或者一个简单的方法可以使用?

MyLibrary.abbreviateHTML(string,20) ?

答案 1

由于正确执行此操作并不容易,因此我通常会剥离所有标签并截断。这很好地控制了文本大小和外观,通常需要将其放置在确实需要控制的位置。

请注意,您可能会发现我的提案非常保守,实际上这不是您问题的正确答案。但大多数时候,替代方案是:

  • 剥离所有标签并截断
  • 提供可管理的可选内容富文本,该格式文本将用作截断的文本。这当然仅适用于CMS等情况

截断HTML很难的原因是你不知道截断会如何影响HTML的结构。你会如何在一个综合体的中间截断,甚至更糟糕的是,在一个综合体的中间?<ul><table>

所以这里的问题是HTML不仅可以包含内容和样式(粗体,斜体),还可以包含结构(列表,表格,div等)。因此,一个好的和安全的实现是将所有内容剥离出内联“样式”标记(粗体,斜体等),并在跟踪未关闭的标记时截断。


答案 2

我不知道任何图书馆,但它不应该那么复杂(80%)。您只需要一个简单的“解析器”,它理解4种类型的令牌:

  • 开始标记 - 以 开头但不以 结尾但以结尾但不是结尾的所有内容<</>/>
  • 结束标记 - 以 开头和结尾的所有内容</>
  • 自结束标记(如 ) - 以 开头但不以结尾但不是结尾的所有内容<br/><<//>>
  • 正常字符 - 不是其他类型的所有内容

然后,您必须遍历输入字符串,并计算“正常字符”。当您沿着字符串和计数进行操作时,只要计数的正常字符小于或等于您想要的数量,就可以将每个令牌复制到输出中。

你还需要构建一堆当前打开的标签,而你走路时认为输入。每次你走过一个“开始标签”时,你把它放在堆栈(它的名字)上,每次你找到一个结束标签,你从堆栈中删除最上面的标签名称(希望输入是正确的XHTML)。

当您达到所需数量的正常字符的末尾时,您只需要为堆栈上剩余的标签名称编写结束HTML标签。

但请注意,这仅适用于格式正确的 XML 输入。

我不知道你想用这段代码做什么,但你应该注意HTML / JavaScript注入攻击。