Meilleure façon de combiner des nœuds avec le pack d'agilité HTML

c# html-agility-pack

Question

J'ai converti un gros document de Word en HTML. C'est proche, mais j'ai un tas de nœuds "code" que j'aimerais fusionner en un nœud "pré".

Voici l'entrée:

<p>Here's a sample MVC Controller action:</p>
<code>        public ActionResult Index()</code>
<code>        {</code>
<code>            return View();</code>
<code>        }</code>
<p>We'll start by making the following changes...</p>

Je veux le transformer en ceci, à la place:

<p>Here's a sample MVC Controller action:</p>
<code>        public ActionResult Index()</code>
<code>        {</code>
<code>            return View();</code>
<code>        }</code>
<p>We'll start by making the following changes...</p>

J'ai fini par écrire une boucle de force brute qui itère les nœuds à la recherche de nœuds consécutifs, mais cela me semble moche:

<p>Here's a sample MVC Controller action:</p>
<code>        public ActionResult Index()</code>
<code>        {</code>
<code>            return View();</code>
<code>        }</code>
<p>We'll start by making the following changes...</p>

Normalement, je supprime les noeuds dans la première boucle, mais cela ne fonctionne pas pendant l'itération, car vous ne pouvez pas modifier la collection lorsque vous le parcourez.

De meilleures idées?

Réponse populaire

La première approche: sélectionnez tous les nœuds <code> , regroupez-les et créez un nœud <pre> par groupe:

var idx = 0;
var nodes = doc.DocumentNode
    .SelectNodes("//code")
    .GroupBy(n => new { 
        Parent = n.ParentNode, 
        Index = n.NextSiblingIsCode() ? idx : idx++ 
    });

foreach (var group in nodes)
{
    var pre = HtmlNode.CreateNode("<pre class='brush: csharp'></pre>");
    pre.AppendChild(doc.CreateTextNode(
        string.Join(Environment.NewLine, group.Select(g => g.InnerText))
    ));
    group.Key.Parent.InsertBefore(pre, group.First());

    foreach (var code in group)
        code.Remove();
}

Le champ de regroupement ici est un champ combiné d'un nœud parent et d'un index de groupe qui est augmenté lorsqu'un nouveau groupe est trouvé. Aussi, j'ai utilisé la méthode d'extension NextSiblingIsCode ici:

var idx = 0;
var nodes = doc.DocumentNode
    .SelectNodes("//code")
    .GroupBy(n => new { 
        Parent = n.ParentNode, 
        Index = n.NextSiblingIsCode() ? idx : idx++ 
    });

foreach (var group in nodes)
{
    var pre = HtmlNode.CreateNode("<pre class='brush: csharp'></pre>");
    pre.AppendChild(doc.CreateTextNode(
        string.Join(Environment.NewLine, group.Select(g => g.InnerText))
    ));
    group.Key.Parent.InsertBefore(pre, group.First());

    foreach (var code in group)
        code.Remove();
}

Il permettait de déterminer si le frère suivant était un nœud <code> .


La deuxième approche: sélectionnez uniquement le nœud <code> de chaque groupe, puis parcourez chacun de ces nœuds pour rechercher le nœud <code> jusqu'au premier nœud non <code> . J'ai utilisé xpath ici:

var idx = 0;
var nodes = doc.DocumentNode
    .SelectNodes("//code")
    .GroupBy(n => new { 
        Parent = n.ParentNode, 
        Index = n.NextSiblingIsCode() ? idx : idx++ 
    });

foreach (var group in nodes)
{
    var pre = HtmlNode.CreateNode("<pre class='brush: csharp'></pre>");
    pre.AppendChild(doc.CreateTextNode(
        string.Join(Environment.NewLine, group.Select(g => g.InnerText))
    ));
    group.Key.Parent.InsertBefore(pre, group.First());

    foreach (var code in group)
        code.Remove();
}



Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Est-ce KB légal? Oui, apprenez pourquoi
Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Est-ce KB légal? Oui, apprenez pourquoi