Finden Sie alle Elemente mit Textzeichenfolge?

c# html html-agility-pack xpath

Frage

Ich versuche, alle HTML-Elemente (Tags) zu entfernen, die eine bestimmte Textzeichenfolge enthalten. Ich habe 2376 html-Dokumente, alle mit verschiedenen Doctype-Standards. Einige haben sogar keinen Doctype (könnte für diese Frage irrelevant sein).

Also suche ich nach einer Textzeichenfolge, die sagt "Wie dieses Papier zitiert wird", und ich habe festgestellt, dass es entweder in einem <p>-tag , <h4>-tag oder einem <legend>-tag .

Der <p>-tag sieht oft so aus,

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

Der <h4>-tag sieht oft so aus,

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

Der <legend>-tag sieht so aus,

<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>

Die Aufgabe besteht darin, diese Tags zu finden und sie aus der Datei zu entfernen und sie dann erneut zu speichern. Ich habe mehr Tags zu entfernen, aber brauche Hilfe, um HAP und XPath zu verstehen, und wie man bestimmte Tags anhand ihrer Werte oder anderer eindeutiger Daten findet.

Bisher habe ich diesen Code in C # entwickelt, es ist eine Konsolenanwendung. Das ist mein Main (Entschuldigung für schlechte Einrückung),

//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();

Und das ist die private Methode, die Verzeichnisse nach Dateien durchsucht,

//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;
    }

Das einzigartige Ding scheint zu sein, "wie man dieses Papier zitiert", also versuche ich, alle spezifischen Umbauten zu finden, die diese genauen Wörter enthalten und sie dann entfernen. Mein Editor zeigt, dass es 1094 Dateien mit dieser Phrase geben sollte, also versuche ich, sie alle zu bekommen. :)

Jede Hilfe sehr geschätzt! :)

Akzeptierte Antwort

Html Agility Pack unterstützt LINQ-Selektoren, was in diesem Fall sehr praktisch ist. Gegeben ein wenig HTML basierend auf dem obigen Beispiel:

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>";

Sie können eine Sammlung von Tags erstellen, die durchsucht werden sollen, entsprechende Knoten auswählen und diese dann entfernen und entfernen:

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);

Mit dem folgenden Ergebnis:

<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

Lizenziert unter: CC-BY-SA with attribution
Nicht verbunden mit Stack Overflow
Lizenziert unter: CC-BY-SA with attribution
Nicht verbunden mit Stack Overflow