XPath / HtmlAgilityPack: come trovare un elemento (a) con un valore specifico per un attributo (href) e trovare colonne di tabelle adiacenti?

c# html html-agility-pack visual-studio xpath

Domanda

Sono piuttosto disperata perché non riesco a capire come ottenere ciò che ho affermato nella domanda. Ho già letto innumerevoli esempi simili ma non ne ho trovato uno che funzioni nella situazione esatta. Quindi, supponiamo di avere il seguente codice:

<table><tr>
<td><a href="url-a">text A</a></td><td><a>id A</a></td><td><a>img A</a></td>
<td><a href="url-b">text B</a></td><td><a>id B</a></td><td><a>img B</a></td>
<td><a href="url-c">text C</a></td><td><a>id C</a></td><td><a>img C</a></td>
</tr></table>

Ora, quello che ho già è una parte di url-a. Fondamentalmente voglio sapere come posso ottenere id A e img A. Sto cercando di "trovare" la linea con XPath ma non riesco a trovare un modo per farlo funzionare. Inoltre, potrebbe essere possibile che l'informazione non sia affatto presente. Questo è il mio ultimo tentativo (seriamente, ho lavorato su questo per più di 3 ore ora provando numerosi modi diversi):

<table><tr>
<td><a href="url-a">text A</a></td><td><a>id A</a></td><td><a>img A</a></td>
<td><a href="url-b">text B</a></td><td><a>id B</a></td><td><a>img B</a></td>
<td><a href="url-c">text C</a></td><td><a>id C</a></td><td><a>img C</a></td>
</tr></table>

Beh, a quanto pare è sbagliato, quindi sarei molto felice se qualcuno potesse aiutarmi qui. Inoltre sarei grato se qualcuno potesse indicarmi un sito Web che spiega XPath e le notazioni / Sintassi in dettaglio con esempi come questo. Anche i libri sono benvenuti

PS: So che potrei raggiungere il mio obiettivo anche senza XPath con Regex o con un semplice StreamReader in C # e controllando se ogni riga contiene ciò di cui ho bisogno ma a) è troppo fragile per le mie esigenze perché il codice potrebbe avere interruzioni di riga improvvise e b) Voglio davvero rimanere coerente con l'adesione completa a XPath per tutto ciò che sto facendo in questo progetto.

Grazie in anticipo per il vostro aiuto!

Risposta accettata

Usa le seguenti espressioni XPath :

   /*/tr/td[a[@href='url-a']]
                /following-sibling::td[1]
                     /a/text()

Se valutato rispetto al documento XML (malformato ma corretto) fornito :

   /*/tr/td[a[@href='url-a']]
                /following-sibling::td[1]
                     /a/text()

il nodo di testo desiderato è selezionato :

   /*/tr/td[a[@href='url-a']]
                /following-sibling::td[1]
                     /a/text()

Allo stesso modo, questa espressione XPath :

   /*/tr/td[a[@href='url-a']]
                /following-sibling::td[1]
                     /a/text()

se valutato rispetto allo stesso documento XML (sopra), seleziona l'altro nodo di testo desiderato :

   /*/tr/td[a[@href='url-a']]
                /following-sibling::td[1]
                     /a/text()

Verifica basata su XSLT :

Quando questa trasformazione viene applicata al documento XML (sopra):

   /*/tr/td[a[@href='url-a']]
                /following-sibling::td[1]
                     /a/text()

i risultati desiderati sono prodotti :

   /*/tr/td[a[@href='url-a']]
                /following-sibling::td[1]
                     /a/text()

Risposta popolare

Hai un codice HTML gravemente danneggiato con tag di td chiusura non corrispondenti. Correggili per favore. È solo una brutta immagine questo markup.

Detto questo, si spera che Html Agility Pack sia in grado di gestire qualsiasi schifezza che ci passi sopra, quindi ecco come procedere e analizzare la spazzatura che hai e trovare i valori id e img dati l' href :

class Program
{
    static void Main()
    {
        var doc = new HtmlDocument();
        doc.Load("test.html");
        var anchor = doc.DocumentNode.SelectSingleNode("//a[contains(@href, 'url-a')]");
        if (anchor != null)
        {
            var id = anchor.ParentNode.SelectSingleNode("following-sibling::td/a");
            if (id != null)
            {
                Console.WriteLine(id.InnerHtml);
                var img = id.ParentNode.SelectSingleNode("following-sibling::td/a");
                if (img != null)
                {
                    Console.WriteLine(img.InnerHtml);
                }
            }
        }
    }
}



Autorizzato sotto: CC-BY-SA with attribution
Non affiliato con Stack Overflow
È legale questo KB? Sì, impara il perché
Autorizzato sotto: CC-BY-SA with attribution
Non affiliato con Stack Overflow
È legale questo KB? Sì, impara il perché