ネストされた要素(ほとんどはdiv要素とp要素のみ)を持つhtmlがありますが、同じ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>
が変数に達したため、後続の文字は削除されます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>
その変数が与えられると、出力はあるmoint maxLength = 7;
に等しくなるはずです。このコードのため、そのようには機能しません:ParentNode = null
lastNode
.Node
.ParentNode
.ReplaceChild(HtmlNode.CreateNode(lastNodeText.InnerText.Substring(0, lastNode.NodeLength - lastNode.TotalLength + maxLength)), lastNode.Node);
新しいHtmlNodeを作成することは、そのInnterTextプロパティが読み取り専用であるため、役に立たないようです。