我有带有嵌套元素的 html(主要是div和p元素)我需要返回相同的 html,但是由给定数量的字母组成。显然字母计数不应该通过html标签来枚举,而只计算每个html元素的InnerText的字母。Html 结果应保留正确的结构 - 任何结束标记以保持有效的 html。
样本输入:
<div>
<p>some text</p>
<p>some more text some more text some more text some more text some more text</p>
<div>
<p>some more text some more text some more text some more text some more text</p>
<p>some more text some more text some more text some more text some more text</p>
</div>
</div>
鉴于int length = 16
输出应如下所示:
<div>
<p>some text</p> // 9 characters in the InnerText here
<p>some mo</p> // 7 characters in the InnerText here; 9 + 7 = 16;
</div>
请注意,字母数(包括空格)为 16。<div>
由于字母数已达到 variable ,因此消除了后续字母length
。请注意,输出 html 仍然有效。
我已经尝试了以下方法,但这并没有真正奏效。输出不符合预期:一些 html 元素被重复。
public static string SubstringHtml(this string html, int length)
{
HtmlDocument doc = new HtmlDocument();
doc.LoadHtml(html);
int totalLength = 0;
StringBuilder output = new StringBuilder();
foreach (var node in doc.DocumentNode.Descendants())
{
totalLength += node.InnerText.Length;
if(totalLength >= length)
{
int difference = totalLength - length;
string lastPiece = node.InnerText.ToString().Substring(0, difference);
output.Append(lastPiece);
break;
}
else
{
output.Append(node.InnerHtml);
}
}
return output.ToString();
}
更新
@SergeBelov 提供了一个适用于第一个示例输入的解决方案,但是进一步的测试显示了一个输入问题,如下所示。
样本输入#2:
some more text some more text
<div>
<p>some text</p>
<p>some more text some more text some more text some more text some more text</
</div>
鉴于该变量int maxLength = 7;
,输出应该等于一些 mo。由于以下代码,它不能那样工作ParentNode = null
:
lastNode
.Node
.ParentNode
.ReplaceChild(HtmlNode.CreateNode(lastNodeText.InnerText.Substring(0, lastNode.NodeLength - lastNode.TotalLength + maxLength)), lastNode.Node);
创建一个新的 HtmlNode 似乎没有帮助,因为它的 IninterText 属性是只读的。