Trova tutti gli elementi con una stringa di testo?

c# html html-agility-pack xpath

Domanda

Sto cercando di rimuovere tutti gli elementi HTML (tag) che contengono una stringa di testo specifica. Ho 2376 documenti html, tutti con diversi standard doctype. Alcuni addirittura non hanno un doctype (potrebbe essere irrilevante a questa domanda).

Quindi, sto cercando una stringa di testo che dice "Come citare questo documento", e ho scoperto che è racchiuso tra un <p>-tag , <h4>-tag o un <legend>-tag .

Il <p>-tag spesso assomiglia a questo,

<p style="text-align : center; color : Red; font-weight : bold;">How to cite this paper:</i></p>

Il <h4>-tag spesso assomiglia a questo,

<h4>How to cite this paper:</h4>Antunes, P., Costa, C.J. &amp; Pino, J.A. (2006).

Il <legend>-tag aspetto,

<legend style="color: white; background-color: maroon; font-size: medium; padding: .1ex .5ex; border-right: 1px solid navy; border-bottom: 1px solid navy; font-weight: bold;">How to cite this paper</legend>

L'operazione da eseguire consiste nel trovare questi tag e rimuoverli dal file e quindi salvare di nuovo il file. Ho altri tag da rimuovere, ma ho bisogno di aiuto per capire HAP e XPath e come localizzare tag specifici in base ai loro valori o ad altri dati univoci.

Finora ho creato questo codice in C #, è un'applicazione per console. Questo è il mio Main (mi dispiace per il rientro negativo),

//Variables
string Ext = "*.html";
string folder = @"D:\websites\dev.openjournal.tld\public\arkivet\";
IEnumerable<string> files = GetHTMLFiles(folder, Ext);
List<string> cite_files = new List<string>();            
var doc = new HtmlDocument();

//Loop to match all html-elements to query
foreach (var file in files)
{
 try
   {
      doc.Load(file);
      cite_files.Add(doc.DocumentNode.SelectNodes("//h4[contains(., 'How to cite this paper')]").ToString()); 

     cite_files.Add(doc.DocumentNode.SelectNodes("//p[contains(., 'How to cite this paper')]").ToString());
   }                
                    catch (Exception Ex)
                    {
                        Console.WriteLine(Ex.Message);
                    }
                }

                //Counts numbers of hits and prints data to user
                int filecount = files.Count();
                int citations = cite_files.Count();            
                Console.WriteLine("Number of files scanned: " + filecount);
                Console.WriteLine("Number of citations: {0}", citations);

                // Program end
                Console.WriteLine("Press any key to close program....");
                Console.ReadKey();

E questo è il metodo privato che guarda attraverso le directory per i file,

//List all HTML-files recursively and return them to a list 
 public static IEnumerable<string> GetHTMLFiles(string directory, string Ext)
    {
        List<string> files = new List<string>();

        try
        {
            files.AddRange(Directory.GetFiles(directory, Ext, SearchOption.AllDirectories));
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
        }            
        return files;
    }

La cosa unica sembra essere "Come citare questo documento", quindi sto cercando di trovare tutti i tag specifici che contengono queste parole esatte e quindi rimuoverli. Il mio Notepad mostra che ci dovrebbero essere 1094 file con questa frase, quindi sto cercando di ottenerli tutti. :)

Qualsiasi aiuto molto apprezzato! :)

Risposta accettata

Html Agility Pack supporta i selettori LINQ, che in questo caso sono molto convenienti. Dato un po 'di HTML basato sul tuo esempio sopra:

var html =
@"<html><head></head><body>

<!-- selector match: delete these nodes -->
<p style='text-align: center; color: Red; font-weight: bold;'>How to cite this paper:</i></p>
<h4> How to cite this paper:</h4> Antunes, P., Costa, C.J. & amp; Pino, J.A. (2006).
<legend style='color: white; background-color: maroon; font-size: medium; padding: .1ex .5ex; border-right: 1px solid navy; border-bottom: 1px solid navy; font-weight: bold;'>How to cite this paper </legend>
<div><p><i><b>How to cite this paper (NESTED)</b></i></p></div>

<!-- no match: keep these nodes -->
<p>DO NOT DELETE - How to cite</p>
<h4>DO NOT DELETE - cite this paper:</h4>
<legend>DO NOT DELETE</legend>

</body></html>";

È possibile creare una raccolta di tag che devono essere cercati, selezionare i nodi corrispondenti, quindi eliminarli in questo modo:

var tagsToDelete = new string[] { "p", "h4", "legend" };
var nodesToDelete = new List<HtmlNode>();

var document = new HtmlDocument();
document.LoadHtml(html);
foreach (var tag in tagsToDelete)
{
    nodesToDelete.AddRange(
        from searchText in document.DocumentNode.Descendants(tag)
            where searchText.InnerText.Contains("How to cite this paper")
            select searchText
    );
}

foreach (var node in nodesToDelete) node.Remove();

document.Save(OUTPUT);

Con il seguente risultato:

<html><head></head><body>

<!-- XPath match: delete these nodes -->

 Antunes, P., Costa, C.J. & amp; Pino, J.A. (2006).

<div></div>

<!-- no match, keep these nodes -->
<p>DO NOT DELETE - How to cite</p>
<h4>DO NOT DELETE - cite this paper:</h4>
<legend>DO NOT DELETE</legend>

</body></html>


Related

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é