Sélectionnez un nœud en fonction des propriétés du même frère - HtmlAgilityPack - C #

c# html-agility-pack html-parsing

Question

J'ai un document HTML structuré comme suit

<ul class="beverageFacts">
<li>
    <span>Vintage</span> 
    <strong>2007&nbsp;</strong>
</li>
<li>
    <span>ABV</span> 
    <strong>13,0&nbsp;%</strong>
</li>
<li>
    <span>Sugar</span> 
    <strong>5&nbsp;gram/liter</strong>
</li>

Je dois analyser les valeurs du <strong> -Tags à correspondant string en fonction de quelle valeur de la <span> -tag a.

J'ai le suivant:

String vintage;
String sugar;
String abv;

A partir de maintenant, je suis Boucler dans chaque nœud enfant des beverageFacts -node vérifier les valeurs pour analyser à la correspondante correcte string . Le code que j'ai jusqu'à présent pour obtenir la valeur "Vintage" est le suivant, bien que le résultat soit toujours null .

HtmlNodeCollection childNodes = bevFactNode.ChildNodes;
foreach (HtmlNode subNode in childNodes)
{
    if (subNode.InnerText.TrimStart() == "Vintage")
        vintage = subNode.NextSibling.InnerText.Trim();
}

Je crois que ma sélection des nœuds est incorrecte, mais je ne peux pas comprendre comment le faire correctement de la manière la plus efficace.

Y a-t-il un moyen facile d'y parvenir?


Edit 2013-07-29

J'ai essayé de supprimer les espaces comme suggéré par enricoariel dans les commentaires en utilisant le code suivant

        HtmlAgilityPack.HtmlDocument page = new HtmlWeb().Load("http://www.systembolaget.se/" + articleID);

        string cleanDoc = Regex.Replace(page.DocumentNode.OuterHtml, @"\s*(?<capture><(?<markUp>\w+)>.*<\/\k<markUp>>)\s*", "${capture}", RegexOptions.Singleline);

        HtmlDocument cleanPage = new HtmlDocument();
        cleanPage.LoadHtml(cleanDoc);

Le résultat est encore

 String vintage = null;

Réponse acceptée

En regardant le balisage HTML, j'ai réalisé que je n'allais pas assez profondément dans les nœuds. Enricoariel a également souligné qu'il y a des espaces que je ne nettoie pas correctement. En sautant la fratrie, qui correspond aux espaces, et en sautant à la suivante, j'obtiens le résultat correct.

        foreach (HtmlNode bevFactNode in bevFactsNodes)
        {
            HtmlNodeCollection childNodes = bevFactNode.ChildNodes;
            foreach (HtmlNode node in childNodes)
            {
                foreach(HtmlNode subNode in node.ChildNodes)
                {
                    if (subNode.InnerText.Trim() == "Årgång")
                        vintage = HttpUtility.HtmlDecode(subNode.NextSibling.NextSibling.InnerText.Trim());
                }
            }
        }
        Console.WriteLine("Vintage: " + vintage);

va sortir

Vintage: 2007

J'ai décodé le code HTML pour obtenir le résultat correctement formaté.

Leçons apprises!


Réponse populaire

Pour résumer, je pense que la meilleure solution serait de supprimer tous les espaces blancs en utilisant une expression rationnelle avant de récupérer la valeur nextSibling:

    string myHtml =
    @"
    <ul class='beverageFacts'>
    <li>
        <span>Vintage</span> 
        <strong>2007&nbsp;</strong>
    </li>
    <li>
        <span>ABV</span> 
        <strong>13,0&nbsp;%</strong>
    </li>
    <li>
        <span>Sugar</span> 
        <strong>5&nbsp;gram/liter</strong>
    </li>";
    //Remove space after and before tag
myHtml = Regex.Replace(myHtml, @"\s+<", "<", RegexOptions.Multiline | RegexOptions.Compiled);
myHtml = Regex.Replace(myHtml, @">\s+", "> ", RegexOptions.Compiled | RegexOptions.Multiline);

HtmlDocument doc = new HtmlDocument();
doc.LoadHtml(myHtml.Replace("/r", "").Replace("/n", "").Replace("/r/n", "").Replace("  ", ""));
doc.OptionFixNestedTags = true;

HtmlNodeCollection vals = doc.DocumentNode.SelectNodes("//ul[@class='beverageFacts']//span");

var myNodeContent = string.Empty;
foreach (HtmlNode val in vals)
{
    if (val.InnerText == "Vintage")
    {
        myNodeContent = val.NextSibling.InnerText;
    }
}

return myNodeContent;


Related

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