テキスト文字列を持つすべての要素を検索しますか?

c# html html-agility-pack xpath

質問

特定のテキスト文字列を含むすべてのhtml要素(タグ)を削除しようとしています。私は2376のhtml文書を持っています。すべてが異なるdoctype標準を持っています。 Doctypeを持っていない人もいます(この質問には関係ないかもしれません)。

だから、「この論文を引用する方法」というテキスト文字列を探していますが、 <p>-tag<h4>-tagまたは<legend>-tagいずれかに囲まれていることがわかりました。

<p>-tagよくこのように見えますが、

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

<h4>-tagよくこのように見えますが、

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

<legend>-tagは次のようになります。

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

手元にあるタスクは、これらのタグを見つけてファイルから削除し、ファイルを再度保存することです。削除するタグが増えましたが、HAPとXPathを理解するための助けと、値やその他の固有のデータに基づいて特定のタグを見つける方法が必要です。

これまで私はC#でこのコードを考え出しました。これはコンソールアプリケーションです。これは私のメインです(悪いインデントで申し訳ありません)。

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

そして、これはディレクトリを通ってファイルを調べるプライベートな方法ですが、

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

ユニークなことは、「この論文を引用する方法」のようです。そのため、これらの正確な単語を含む特定のタグをすべて見つけようとしています。私のメモ帳には、このフレーズに1094個のファイルがあるはずなので、それらをすべて取得しようとしています。 :)

どのような助けが大いに感謝! :)

受け入れられた回答

Html Agility PackはLINQセレクタをサポートしていますが、この場合は非常に便利です。上記の例に基づいてHTMLをいくつか考えてみましょう:

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

検索するタグのコレクションを作成し、一致するノードを選択してから、次のように削除することができます。

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

次の結果が得られました。

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



ライセンスを受けた: CC-BY-SA with attribution
所属していない Stack Overflow
このKBは合法ですか? はい、理由を学ぶ
ライセンスを受けた: CC-BY-SA with attribution
所属していない Stack Overflow
このKBは合法ですか? はい、理由を学ぶ