c# – 截断文本块末尾的HTML内容(块元素)
主要是当我们缩短/截短文本内容时,我们通常只是在特定的字符索引上截断它.这在
HTML中已经很复杂了,但是我想使用不同的度量来截断我的HTML内容(使用content-editable div生成):
>我将定义将用作截断起始点限制的字符索引N 我的内容可编辑的生成内容可能包含段落(带换行符),预格式化的代码块,块引号,有序和无序列表,标题,粗体和斜体(它们是内联节点,不应该在截断过程中计数)等.实施当然将定义哪些要素具体是可能的截断候选者.标题尽管它们是块HTML元素不会被视为截断点,因为我们不想要遗ed头.段落,列出单个项目,整个有序和无序列表,预格式化块,空白元素等都是好的.标题和所有内嵌块元素不是. 例 我们来看一下这个非常stackoverflow的问题,作为我要截断的HTML内容的例子.我们将截断限制设置为1000,偏移量为250个字符(1/4). This DotNetFiddle显示此问题的文本,同时在其中添加极限标记(| MIN |表示字符750,| LIMIT |表示字符1000和| MAX |,表示字符1250). 从示例可以看出,两个块节点之间到字符1000的最近的截断边界在< / OL>之间.和P(我的内容可编辑生成…).这意味着我的HTML应该被截断在这两个标签之间,这将导致一点点不到1000个字符长的内容文本明智,但保留截断的内容有意义,因为它不会只是截断在某些文本段落的某个地方. 我希望这解释了这个算法应该如何工作. 问题 我在这里看到的第一个问题是我正在处理像HTML这样的嵌套结构.我还必须检测不同的元素(只有块元素,没有内联的元素).最后但并非最不重要的是,我只需要计算字符串中的某些字符,并忽略属于标签的字符. 可能的解决方案 >我可以通过创建一些表示内容节点及其层次结构的对象树来手动解析我的内容 第二个想法 我确定我可以做#1,但感觉到我正在重塑轮子. 如何一种方法这样的截断算法?我的头似乎太累了,不能达成共识(或解决方案). 解决方法
这是一些可以截断内部文本的示例代码.它使用InnerText属性和CloneNode方法的递归功能.
public static HtmlNode TruncateInnerText(HtmlNode node,int length) { if (node == null) throw new ArgumentNullException("node"); // nothing to do? if (node.InnerText.Length < length) return node; HtmlNode clone = node.CloneNode(false); TruncateInnerText(node,clone,length); return clone; } private static void TruncateInnerText(HtmlNode source,HtmlNode root,HtmlNode current,int length) { HtmlNode childClone; foreach (HtmlNode child in source.ChildNodes) { // is expected size is ok? int expectedSize = child.InnerText.Length + root.InnerText.Length; if (expectedSize <= length) { // yes,just clone the whole hierarchy childClone = child.CloneNode(true); current.ChildNodes.Add(childClone); continue; } // is it a text node? then crop it HtmlTextNode text = child as HtmlTextNode; if (text != null) { int remove = expectedSize - length; childClone = root.OwnerDocument.CreateTextNode(text.InnerText.Substring(0,text.InnerText.Length - remove)); current.ChildNodes.Add(childClone); return; } // it's not a text node,shallow clone and dive in childClone = child.CloneNode(false); current.ChildNodes.Add(childClone); TruncateInnerText(child,root,childClone,length); } } 还有一个示例C#控制台应用程序,将把这个问题作为一个例子,并将其截断为500个字符. class Program { static void Main(string[] args) { var web = new HtmlWeb(); var doc = web.Load("https://stackoverflow.com/questions/30926684/truncating-html-content-at-the-end-of-text-blocks-block-elements"); var post = doc.DocumentNode.SelectSingleNode("//td[@class='postcell']//div[@class='post-text']"); var truncated = TruncateInnerText(post,500); Console.WriteLine(truncated.OuterHtml); Console.WriteLine("Size: " + truncated.InnerText.Length); } } 当它运行它应该显示: <div class="post-text" itemprop="text"> <p>Mainly when we shorten/truncate textual content we usually just truncate it at specific character index. That's already complicated in HTML anyway,but I want to truncate my HTML content (generated using content-editable <code>div</code>) using different measures:</p> <ol> <li>I would define character index <code>N</code> that will serve as truncating startpoint <em>limit</em></li> <li>Algorithm will check whether content is at least <code>N</code> characters long (text only; not counting tags); if it's not it will just return the whole content</li> <li>It would then</li></ol></div> Size: 500 注意:我没有在字边界截断,只是在字符边界,而不是,根本不符合我的意见建议:-) (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |