2016-09-30 92 views
1

我有一個html代碼作爲字符串。我需要找到該字符串中的所有img標籤,讀取每個src屬性的值並將其傳遞給一個函數,該函數返回需要取代讀取的img標籤的整個img標籤。遍歷html字符串來查找所有img標籤並替換src屬性值

它需要遍歷整個字符串並對所有img標籤執行相同的邏輯。

例如,假設我的HTML字符串如下所示:

string htmlBody= "<p>Hi everyone</p><img src=\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAMAAACdt4HsAAAA..." <p>I am here </p> <img src=\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABAC..." />" 

我有下面的代碼,找到的第一個img標籤,取src值(這是一個base64字符串),並把它轉換成一個位數組來創建一個流,然後我可以創建一個新的src值鏈接到該流。

//Remove from all src attributes "data:image/png;base64"  
    string res = Regex.Replace(htmlBody, "data:image\\/\\w+\\;base64\\,", ""); 
    //Match the img tag and get the base64 string value 
    string matchString = Regex.Match(res, "<img.+?src=[\"'](.+?)[\"'].*?>", RegexOptions.IgnoreCase).Groups[1].Value; 
    var imageData = Convert.FromBase64String(matchString); 
    var contentId = Guid.NewGuid().ToString(); 
    LinkedResource inline = new LinkedResource(new MemoryStream(imageData), "image/jpeg"); 
    inline.ContentId = contentId; 
    inline.TransferEncoding = TransferEncoding.Base64; 
    //Replace all img tags with the new img tag 
    htmlBody = Regex.Replace(htmlBody, "<img.+?src=[\"'](.+?)[\"'].*?>", @"<img src='cid:" + inline.ContentId + @"'/>"); 

正如你可以看到finnaly我已經拿到了新的img標籤來代替:

<img src='cid:" + inline.ContentId + @"'/> 

但代碼將取代具有相同內容的所有img標籤。我需要能夠獲得img標籤,執行邏輯,替換它,然後繼續使用下一個img標籤。

希望你能給我一個想法,我可以做到這一點。提前致謝。

回答

2

如果我明白您的需要,您可以使用HtmlAgilityPack來達到此目的。使用正則表達式可能會導致不需要的行爲。你可以試試下面的代碼嗎?

public static string DoIt() 
{ 
     string htmlString = ""; 
     using (WebClient client = new WebClient()) 
      htmlString = client.DownloadString("http://dean.edwards.name/my/base64-ie.html"); //This is an example source for base64 img src, you can change this directly to your source. 

     HtmlDocument document = new HtmlDocument(); 
     document.LoadHtml(htmlString); 
     document.DocumentNode.Descendants("img") 
          .Where(e => 
          { 
           string src = e.GetAttributeValue("src", null) ?? ""; 
           return !string.IsNullOrEmpty(src) && src.StartsWith("data:image"); 
          }) 
          .ToList() 
          .ForEach(x => 
          { 
           string currentSrcValue = x.GetAttributeValue("src", null); 
           currentSrcValue = currentSrcValue.Split(',')[1];//Base64 part of string 
           byte[] imageData = Convert.FromBase64String(currentSrcValue); 
           string contentId = Guid.NewGuid().ToString(); 
           LinkedResource inline = new LinkedResource(new MemoryStream(imageData), "image/jpeg"); 
           inline.ContentId = contentId; 
           inline.TransferEncoding = TransferEncoding.Base64; 

           x.SetAttributeValue("src", "cid:" + inline.ContentId); 
          }); 


     string result = document.DocumentNode.OuterHtml; 
} 

您可以從https://www.nuget.org/packages/HtmlAgilityPack

希望檢索HtmlAgilityPack這有助於

+0

謝謝@Cihan。它工作得很好 –

+0

不客氣@ D.B –

2

我認爲你需要重複你的每一個牽強的img格式串碼。 下面的代碼給你所有的img標籤的列表:

public static List<string> FetchImgsFromSource(string htmlSource) 
     { 
      List<string> listOfImgdata = new List<string>(); 
      string regexImgSrc = @"<img[^>]*?src\s*=\s*[""']?([^'"" >]+?)[ '""][^>]*?>"; 
      MatchCollection matchesImgSrc = Regex.Matches(htmlSource, regexImgSrc, RegexOptions.IgnoreCase | RegexOptions.Singleline); 
      foreach (Match m in matchesImgSrc) 
      { 
       string href = m.Groups[1].Value; 
       listOfImgdata.Add(href); 
      } 
      return listOfImgdata; 
     } 

使用這個列表和用戶邏輯的循環:

foreach (var item in listOfImgdata) 
      { 
       var imageData = Convert.FromBase64String(item); 
       var contentId = Guid.NewGuid().ToString(); 
       LinkedResource inline = new LinkedResource(new MemoryStream(imageData), "image/jpeg"); 
       inline.ContentId = contentId; 
       inline.TransferEncoding = TransferEncoding.Base64; 
       //Replace all img tags with the new img tag 
       htmlBody = Regex.Replace(htmlBody, "<img.+?src=[\"'](.+?)[\"'].*?>", @"<img src='cid:" + inline.ContentId + @"'/>"); 
      } 

希望它爲你工作。

解析HTML dom的最佳方式是使用HtmlAgilityPack,如其他人所述。

+0

謝謝@Pramodab。這是一個好方法。唯一的問題是最後一行代碼將所有圖像替換爲最新的html img標籤。也許它可以改善,但是「Cihan」答案在HtmlAgilityPack中效果很好。 –

相關問題