Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>The first approach: select all the <code>&lt;code&gt;</code> nodes, group them, and create a <code>&lt;pre&gt;</code> node per group:</p> <pre><code>var idx = 0; var nodes = doc.DocumentNode .SelectNodes("//code") .GroupBy(n =&gt; new { Parent = n.ParentNode, Index = n.NextSiblingIsCode() ? idx : idx++ }); foreach (var group in nodes) { var pre = HtmlNode.CreateNode("&lt;pre class='brush: csharp'&gt;&lt;/pre&gt;"); pre.AppendChild(doc.CreateTextNode( string.Join(Environment.NewLine, group.Select(g =&gt; g.InnerText)) )); group.Key.Parent.InsertBefore(pre, group.First()); foreach (var code in group) code.Remove(); } </code></pre> <p>The grouping field here is combined field of a parent node and group index which is increased when new group is found. Also I used <code>NextSiblingIsCode</code> extension method here:</p> <pre><code>public static bool NextSiblingIsCode(this HtmlNode node) { return (node.NextSibling != null &amp;&amp; node.NextSibling.Name == "code") || (node.NextSibling is HtmlTextNode &amp;&amp; node.NextSibling.NextSibling != null &amp;&amp; node.NextSibling.NextSibling.Name == "code"); } </code></pre> <p>It used to determine whether the next sibling is a <code>&lt;code&gt;</code> node. <hr /> The second approach: select only the top <code>&lt;code&gt;</code> node of each group, then iterate through each of these nodes to find the next <code>&lt;code&gt;</code> node until the first non-<code>&lt;code&gt;</code> node. I used <code>xpath</code> here:</p> <pre><code>var nodes = doc.DocumentNode.SelectNodes( "//code[name(preceding-sibling::*[1])!='code']" ); foreach (var node in nodes) { var pre = HtmlNode.CreateNode("&lt;pre class='brush: csharp'&gt;&lt;/pre&gt;"); node.ParentNode.InsertBefore(pre, node); var content = string.Empty; var next = node; do { content += next.InnerText + Environment.NewLine; var previous = next; next = next.SelectSingleNode("following-sibling::*[1][name()='code']"); previous.Remove(); } while (next != null); pre.AppendChild(doc.CreateTextNode( content.TrimEnd(Environment.NewLine.ToCharArray()) )); } </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload