使用HtmlAgilityPack检测图像src中的数据URI

时间:2016-04-08 12:14:16

标签: c# base64 html-agility-pack

我处理了很多html并将其转换为PDF文件。在我可以转换我的html之前,我必须检测是否有任何图像是引用文件。如果它是一个引用文件,那么我对它们进行base64编码并用它替换src。

现在我依靠Regex为我做检测,但由于我正在使用HtmlAgilityPack,我想知道我是否能用HtmlAgilityPack实现相同的目标?

我想这样做,所以当我目前已经在使用HtmlAgilityPack时,我不需要维护正则表达式。

现在我正在通过RegEx检测数据uri,其中包含以下内容:

void Main()
{
    var myHtml = @"<html><head></head><body><p><img src='data:image/gif;base64,R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs='/></p></body></html>";
    var htmlDoc = new HtmlDocument();
    htmlDoc.LoadHtml(myHtml);

    var imgs = htmlDoc.DocumentNode.SelectNodes("//img");
    if (imgs != null && imgs.Count > 0)
    {
        foreach (var imgNode in imgs)
        {
            var srcAttribute = imgNode.Attributes.FirstOrDefault(a => string.Equals("src", a.Name, StringComparison.InvariantCultureIgnoreCase));

            if (!string.IsNullOrEmpty(srcAttribute?.Value) && !StringIsDataUri(srcAttribute.Value))
            {
                Console.WriteLine("BASE ENCODE THE REFERENCED FILE");
            }
        }
    }
}

//Regex from http://stackoverflow.com/a/5714355/1958344
private static Regex regex = new Regex(@"data:(?<mime>[\w/\-\.]+);(?<encoding>\w+),(?<data>.*)", RegexOptions.Compiled);

private bool StringIsDataUri(string stringToTest)
{
    var match = regex.Match(stringToTest);
    return match.Success;
}

1 个答案:

答案 0 :(得分:3)

HtmlAgilityPack没有内置函数来检测数据URI,因此您仍需要合并自己的此类函数实现。

另外,您可以使用HtmlAgilityPack的LINQ API来选择首先具有引用img属性的src元素:

var referenceImgs = htmlDoc.DocumentNode
                           .Descendants("img")
                           .Where(o => !StringIsDataUri(o.GetAttributeValue("src","")));

foreach(HtmlNode img in referenceImgs)
{
    Console.WriteLine("BASE ENCODE THE REFERENCED FILE");
}