2017-01-06 4 views
0

ich den Tisch zu bekommen, die sich direkt hinter einem Element befindet:Holen Sie sich das Tisch direkt hinter einem Element

<body> 
    <h3>test</h3> 
    <table> 
     <tr><td>abc</td></tr> 
    </table> 

    <h3>test2</h3> 
    <table> 
     <tr><td>def</td></tr> 
    </table> 
    [...] 
</body> 

Deshalb möchte ich nur die Tabelle nach dem h3 Element „Test“ bekommen (oder den Inhalt von der Tabelle, aber ich weiß, wie man diese Art von Sachen macht). Die Tabelle "Test" steht nicht immer an erster Stelle, könnte auch irgendwo nach der Sekunden-Tabelle liegen.


[Bearbeiten]

Wissen Sie, warum dieser Code:

var doc = new HtmlAgilityPack.HtmlDocument(); 
doc.LoadHtml(html); //your test html 
var s = doc.DocumentNode.Descendants("table").Where(_ => _.PreviousSibling.PreviousSibling.Name.Equals("h3") && _.PreviousSibling.PreviousSibling.InnerText.Equals("test")); 
foreach (var st in s) 
{ 
    Debug.WriteLine(st.InnerHtml); 
} 

funktioniert nicht, wenn ich die Rückkehr nach "/ h3" und "table" entfernen?

Es sieht wie folgt aus:

string html = @"<body><h3>test</h3><table><tr><td>abc</td></tr></table><h3>test2</h3><table><tr><td>def</td></tr></table></body>" 

anstelle der HTML-Code, oben aber das Ergebnis null ist ...

Antwort

0

Sie können so etwas versuchen. Ich finde, dass Linq handlicher ist. Es ist nur eine Idee, dass du es weiter ausbauen kannst oder poste einfach dein Problem hier, wir können es ausarbeiten :). Entschuldigung, ich hatte keine IDE mit mir.

var doc = new HtmlAgilityPack.HtmlDocument(); 
doc.LoadHtml(html); //your test html 
doc.DocumentNode.Descendants("table").Where(_ => _.PreviousSibling.PreviousSibling.Name.Equals("h3")); 

Btw, der Grund, warum wir previousSibling zweimal aufrufen müssen, ist, dass es immer 1 #text Element zwischen den einzelnen Knoten gibt.

+0

Aber wie suche ich nach dem Text in h3 (Test)? Weil ich zwei h3 –

+0

So etwas wie das? 'doc.DocumentNode.Nachfolger ("Tabelle"). Where (_ => _.PreviousSibling.PreviousSibling.Name.Equals ("h3") && _.VorherigesSibling.PreviousSibling.InnerText.Equals ("test")); ' –

+0

Ok danke: D –

0

Diese für XPath klingt wie etwas:

var doc = new HtmlAgilityPack.HtmlDocument(); 
doc.LoadHtml(html); //your test html 
var table = doc.DocumentNode.SelectSingleNode("//h3[text()='test']/following::table"); 
return table.InnerHtml; //returns: "\r\n  <tr><td>abc</td></tr>\r\n " 

XPath aus : XPath - Select first element after some other element

EDIT: Bild des genauen code: enter image description here

EDIT 2: Ihr Problem ist, dass es nicht unbedingt ein Textelement gibt. So können Sie dies lösen, indem Sie eine Überprüfung dafür vornehmen:

var table3 = doc.DocumentNode.Descendants().FirstOrDefault(x => 
      { 
       if (x.NodeType == HtmlAgilityPack.HtmlNodeType.Element) 
       { 
        if (x.PreviousSibling?.NodeType == HtmlAgilityPack.HtmlNodeType.Text) 
        { 
         return x.PreviousSibling.PreviousSibling?.Name == "h3" && x.PreviousSibling.PreviousSibling?.InnerText == "test"; 
        } else 
        { 
         return x.PreviousSibling?.Name == "h3" && x.PreviousSibling?.InnerText == "test"; 
        } 
       } 
       return false; 
      }); 
+0

Ok, thx. Ich werde es ausprobieren –

+0

Für mich funktioniert es leider nicht. Ich muss eine foreach Schleife öffnen, damit ich auf table.InnerHtml zurückgreifen kann (Tabelle ist ein arrey, nicht sicher über dieses aber etwas wie dieses). –

+0

, aber es gibt immer noch Null –

Verwandte Themen