2011-02-11 123 views
7

這似乎是一個反覆出現的問題,但這裏有。如何解析HTML來修改所有單詞

我有格式良好的HTML(它來自一個受控源,所以這可以被認爲是給定的)。我需要遍歷HTML正文的內容,查找文檔中的所有單詞,對這些單詞執行一些編輯,然後保存結果。

例如,我有文件sample.html,我想通過我的應用程序和產品output.html運行它,它與原始文件完全相同,並加上我的編輯。

我發現了以下使用HTMLAgilityPack,但我發現所有的例子看看指定標籤的屬性 - 是否有一個簡單的修改,看看內容和執行我的編輯?

HtmlDocument HD = new HtmlDocument(); 
HD.Load (@"e:\test.htm"); 
var NoAltElements = HD.DocumentNode.SelectNodes("//img[not(@alt)]"); 
if (NoAltElements != null) 
{ 
    foreach (HtmlNode HN in NoAltElements) 
    { 
     HN.Attributes.Append("alt", "no alt image"); 
    } 
} 

HD.Save(@"e:\test.htm"); 

以上看起來沒有ALT標籤的圖像標籤。我想查找文件<body>中的所有標籤,並對內容執行某些操作(可能涉及在此過程中創建新標籤)。

一個非常簡單的我可以做什麼樣的是採取以下輸入:

<html> 
    <head><title>Some Title</title></head> 
    <body> 
     <h1>This is my page</h1> 
     <p>This is a paragraph of text.</p> 
    </body> 
</html> 

,併產生輸出,這需要使它大寫並使其斜體之間的每一個字和候補委員:

<html> 
    <head><title>Some Title</title></head> 
    <body> 
     <h1>THIS <em>is</em> MY <em>page</em></h1> 
     <p>THIS <em>is</em> A <em>paragraph</em> OF <em>text</em>.</p> 
    </body> 
</html> 

想法,建議?

回答

5

就個人而言,考慮到這個設置,我會使用HtmlNode的InnerText屬性來查找單詞(可能使用正則表達式,這樣我可以排除標點符號而不是簡單地依賴空格),然後使用InnerHtml屬性來製作使用對Regex.Replace的迭代調用進行更改(因爲Regex.Replace的方法允許您指定替換的起始位置和次數)。

處理代碼:

IEnumerable<HtmlNode> nodes = doc.DocumentNode.DescendantNodes().Where(n => n.InnerText == "something"); 
foreach (HtmlNode node in nodes) 
{ 
    string[] words = getWords(node.InnerText); 

    node.InnerHtml = processHtml(node.InnerHtml, words); 
} 

識別字(有可能是一些滑頭的方式來做到這一點,但這裏是一個初始刺):

private string[] getWords(string text) 
{ 
    Regex reg = new Regex("/w+"); 
    MatchCollection matches = reg.Matches(text); 
    List<string> words = new List<string>(); 
    foreach (Match match in matches) 
    { 
     words.Add(match.Value); 
    } 
    return words.ToArray(); 
} 

處理HTML:

private string processHtml(string html, string[] words) 
{ 
    int startPosition = 0; 
    foreach (string word in words) 
    { 
     startPosition = html.IndexOf(word, startPosition); 
     Regex reg = new Regex(word); 
     html = reg.Replace(html, alterWord(word), 1, startPosition); 
    } 

    return html; 
} 

我將把alterWord()的細節留給你。 :)

3

嘗試.SelectNodes("//body//*")。這可以讓你在任何深度的任何元素內獲得所有元素。

+0

但是,如何迭代該標籤的內容,以便能夠解析出每個不是標籤的單詞? – Elie 2011-02-11 16:37:33

+0

在這一點上,你幾乎必須依靠處理元素的內容作爲一個字符串,可能使用正則表達式。 – Flynn1179 2011-02-11 16:39:18