Obtention de contenu entre deux balises HTML à l'aide de Html Agility Pack

.net c# html-agility-pack

Question

Nous avons créé un document d'aide absolument massif dans Word, qui a été utilisé pour générer un document HTM encore plus massif et plus banal. À l’aide de C # et de cette bibliothèque, je souhaite uniquement extraire et afficher une section de ce fichier à un moment quelconque de mon application. Les sections sont divisées comme suit:

<!--logical section starts here -->
<div>
<h1><span style='mso-spacerun:yes'></span><a name="_Toc325456104">Section A</a></h1>
</div>
 <div> Lots of unnecessary markup for simple formatting... </div>
 .....
<!--logical section ends here -->

<div>
<h1><span style='mso-spacerun:yes'></span><a name="_Toc325456104">Section B</a></h1>
</div>

Logiquement parlant, il y a un H1 avec un nom de section dans une a étiquette. Je veux tout sélectionner de la div contenant contenant jusqu'à ce que je rencontre un autre h1 et exclure cette div.

  • Chaque nom de section est situé dans une balise <a> sous un h1 qui a plusieurs enfants (environ 6 chacun)
  • La section logique est marquée avec des commentaires
  • Ces commentaires n'existent pas dans le document même

Ma tentative:

var startNode = helpDocument.DocumentNode.SelectSingleNode("//h1/a[contains(., '"+sectionName+"')]");
//go up one level from the a node to the h1 element
startNode=startNode.ParentNode;

//get the start index as the index of the div containing the h1 element
int startNodeIndex = startNode.ParentNode.ChildNodes.IndexOf(startNode);

//here I am not sure how to get the endNode location. 
var endNode =?;

int endNodeIndex = endNode.ParentNode.ChildNodes.IndexOf(endNode);

//select everything from the start index to the end index
var nodes = startNode.ParentNode.ChildNodes.Where((n, index) => index >= startNodeIndex && index <= endNodeIndex).Select(n => n);

Comme je n’ai pas pu trouver de documentation à ce sujet, je ne sais pas comment je peux passer de mon noeud de départ au prochain élément h1. Toute suggestion serait appréciée.

Réponse acceptée

Je pense que cela va le faire, même si cela suppose que les balises H1 apparaissent uniquement dans les en-têtes de section. Si ce n'est pas le cas, vous pouvez ajouter un élément Where sur les descendants pour rechercher d'autres filtres sur les nœuds H1 détectés. Notez que cela inclura tous les frères et sœurs du div trouvé jusqu’à ce qu’il vienne au prochain avec un nom de section.

private List<HtmlNode> GetSection(HtmlDocument helpDocument, string SectionName)
{
    HtmlNode startNode = helpDocument.DocumentNode.Descendants("div").Where(d => d.InnerText.Equals(SectionName, StringComparison.InvariantCultureIgnoreCase)).FirstOrDefault();
    if (startNode == null)
        return null; // section not found

    List<HtmlNode> section = new List<HtmlNode>();
    HtmlNode sibling = startNode.NextSibling;
    while (sibling != null && sibling.Descendants("h1").Count() <= 0)
    {
        section.Add(sibling);
        sibling = sibling.NextSibling;
    }

    return section;
}

Réponse populaire

Donc, ce que vous voulez vraiment comme résultat, c'est la division autour du h1-Tag? Si oui, alors cela devrait fonctionner.

helpDocument.DocumentNode.SelectSingleNode("//h1/a[contains(@name, '"+sectionName+"')]/ancestor::div");

SelectNodes également avec SelectNodes fonction de votre SelectNodes HTML. Comme ça:

helpDocument.DocumentNode.SelectNodes("//h1/a[starts-with(@name,'_Toc')]/ancestor::div");

Oh, et en testant cela, j'ai remarqué que la chose qui ne fonctionnait pas pour moi était le point dans la méthode contient, une fois que je le change en attribut name tout fonctionne correctement.




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