Ich mache einige HTML-Parsing und ich verwende HtmlAgilityPack und ich versuche zu überprüfen, ob ein Knotenelement sichtbar wäre, wenn das HTML in einem Browser gerendert wurde.
Wenn ich sichtbar bin, bin ich wahrscheinlich damit zufrieden, die display
und visibility
zu überprüfen. (es sei denn, es gibt etwas Zusätzliches, um das ich mich kümmern sollte?).
Also, wie kann ich das tun? Gibt es einen Build in einfacher Weise? Kann ich etwas XPath Magie benutzen? (Ich habe im Moment zu wenig Wissen über XPath).
Ich habe darüber nachgedacht, den Style-Wert manuell zu analysieren, würde dies aber als letzten Ausweg speichern. Oder ist das meine einzige Option?
Nur zur Bezugnahme, das Objekt, mit dem ich arbeite, ist ungefähr so:
HtmlAgilityPack.HtmlNode node = GetNode();
OK, also habe ich es geschafft, zumindest für meine Bedürfnisse. Bitte seien Sie jedoch gewarnt, da andere Kommentare gesprochen haben, können Sie nicht überprüfen, ob ein Element (auf dem Bildschirm) für den Endbenutzer sichtbar ist.
Der Ansatz, den ich gewählt habe, überprüft einige Grundregeln: Ein Element ist "nicht sichtbar", wenn das Stilattribut für das Element display:none
oder visibility:hidden
ODER ein Vorgängerelement die gleichen Stilregeln hat.
In diesem Sinne ist hier mein Code, der die Arbeit für mich erledigt:
private static bool IsNodeVisible(HtmlAgilityPack.HtmlNode node)
{
var attribute = node.Attributes["style"];
bool thisVisible = false;
if (attribute == null || CheckStyleVisibility(attribute.Value))
thisVisible = true;
if (thisVisible && node.ParentNode != null)
return IsNodeVisible(node.ParentNode);
return thisVisible;
}
private static bool CheckStyleVisibility(string style)
{
if (string.IsNullOrWhiteSpace(style))
return true;
var keys = ParseHtmlStyleString(style);
if (keys.Keys.Contains("display"))
{
string display = keys["display"];
if (display != null && display == "none")
return false;
}
if (keys.Keys.Contains("visibility"))
{
string visibility = keys["visibility"];
if (visibility != null && visibility == "hidden")
return false;
}
return true;
}
public static Dictionary<string, string> ParseHtmlStyleString(string style)
{
Dictionary<string, string> result = new Dictionary<string, string>();
style = style.Replace(" ", "").ToLowerInvariant();
string[] settings = style.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
foreach (string s in settings)
{
if (!s.Contains(':'))
continue;
string[] data = s.Split(':');
result.Add(data[0], data[1]);
}
return result;
}
Der Einstiegspunkt dafür ist IsNodeVisible
und überprüft die Sichtbarkeit des an ihn übergebenen HtmlNode
.