Un modo migliore per aggiungere un attributo di stile a Html usando HtmlAgilityPack

c# html html-agility-pack

Domanda

Sto usando HtmlAgilityPack. Sto cercando tra tutti i tag P e aggiungendo un "margin-top: 0px" allo stile all'interno del tag P.

Come puoi vedere, è un po 'un "forzato brutale" l'attributo margin-top. Sembra che ci sia un modo migliore per farlo usando HtmlAgilityPack ma non sono riuscito a trovarlo e la documentazione di HtmlAgilityPack è inesistente.

Qualcuno conosce un modo migliore?

        HtmlNodeCollection pTagNodes = node.SelectNodes("//p[not(contains(@style,'margin-top'))]");
        if (pTagNodes != null && pTagNodes.Any())
        {
            foreach (HtmlNode pTagNode in pTagNodes)
            {
                if (pTagNode.Attributes.Contains("style"))
                {
                    string styles = pTagNode.Attributes["style"].Value;
                    pTagNode.SetAttributeValue("style", styles + "; margin-top: 0px");
                }
                else
                {
                    pTagNode.Attributes.Add("style", "margin-top: 0px");
                }
            }
        }



AGGIORNAMENTO : ho modificato il codice in base ai suggerimenti di Alex. Vorrebbe comunque sapere se esiste una funzionalità incorporata in HtmlAgilityPack che gestirà gli attributi di stile in un modo più "DOM".

        const string margin = "; margin-top: 0px";

        HtmlNodeCollection pTagNodes = node.SelectNodes("//p[not(contains(@style,'margin-top'))]");
        if (pTagNodes != null && pTagNodes.Any())
        {
            foreach (var pTagNode in pTagNodes)
            {
                string styles = pTagNode.GetAttributeValue("style", "");
                pTagNode.SetAttributeValue("style", styles + margin);
            }
        }

Risposta accettata

Potresti semplificare un po 'il tuo codice usando il metodo HtmlNode.GetAttributeValue e rendendo costante la tua stringa magica "margin-top" :

const string margin = "margin-top: 0";
foreach (var pTagNode in pTagNodes)
{
    var styles = pTagNode.GetAttributeValue("style", null);
    var separator = (styles == null ? null : "; ");
    pTagNode.SetAttributeValue("style", styles + separator + margin);
}

Non un miglioramento molto significativo, ma questo codice è più semplice per me.


Risposta popolare

Prima di tutto, sei sicuro di aver bisogno di più di quello che hai chiesto? La soluzione di Alex dovrebbe funzionare bene per il tuo problema attuale, se è sempre così "semplice" perché preoccuparsi e aggiungere più complessità ad esso?

Anway, l'AgilityPack non ha quel tipo di funzione, ma sicuramente il .Net Framework ha. Nota questo è tutto per .Net 4, se stai usando una versione precedente le cose potrebbero essere un po 'diverse. Prima di tutto, System.Web.dll viene fornito con la CssStyleCollection Class , questa classe ha già tutto il necessario per analizzare il css in linea, c'è solo un problema, il costruttore è interno, quindi la soluzione è un po '"hacky". Prima di tutto, per costruire un'istanza della classe tutto ciò di cui hai bisogno è un po 'di riflessione, il codice per questo è già stato fatto qui . Tieni presente che ora funziona, ma potrebbe rompere in una versione futura di .Net. Tutto ciò che è rimasto è davvero facile

CssStyleCollection css = CssStyleTools.Create();
css.Value = "border-top:1px dotted #BBB;margin-top: 0px;font-size:12px";
Console.WriteLine(css["margin-top"]); //prints "0px"

Se non puoi per qualche ragione aggiungere un riferimento a System.Web (sarebbe il caso se stai usando .Net 4 Client Profile) c'è sempre la possibilità di usare Reflector.

Personalmente andrei con la soluzione di Alex, ma sta a te decidere. :)



Related

Autorizzato sotto: CC-BY-SA with attribution
Non affiliato con Stack Overflow
Autorizzato sotto: CC-BY-SA with attribution
Non affiliato con Stack Overflow