在大型html文档中为图像添加缺少的alt标签的最有效方法

Dan*_*anP 5 html c# accessibility

为了符合可访问性标准,我需要确保一些动态生成的html(我无法控制)中的所有图像都有一个空的alt标记(如果没有指定).

输入示例:

<html>
    <body>
          <img src="foo.gif" />
          <p>Some other content</p>
          <img src="bar.gif" alt="" />
          <img src="blah.gif" alt="Blah!" />
    </body>
</html>
Run Code Online (Sandbox Code Playgroud)

期望的输出:

<html>
    <body>
          <img src="foo.gif" alt="" />
          <p>Some other content</p>
          <img src="bar.gif" alt="" />
          <img src="blah.gif" alt="Blah!" />
    </body>
</html>
Run Code Online (Sandbox Code Playgroud)

html可能非常大并且DOM严重嵌套,所以使用类似Html Agility Pack的东西就出来了.

谁能建议一种有效的方法来实现这一目标?

更新:

我可以安全地假设我正在处理的html格式正确,因此潜在的解决方案根本不需要考虑.

Jam*_*rgy 3

您的问题似乎非常具体,您需要更改一些输出,但出于性能原因,您不想使用(通用的东西)HTMLAgilityPack 解析整个内容。最好的解决办法似乎是采取困难的方式。

我只会暴力破解它。很难比这样更有效地做到这一点(完全未经测试,几乎保证不会完全按原样工作,但如果在某处缺少“+1”或“-1”,逻辑应该没问题):

string addAltTag(string html) {
    StringBuilder sb = new StringBuilder();
    int pos=0;
    int lastPos=0;
    while(pos>=0) {
       int nextpos;
       pos=html.IndexOf("<img",pos);
       if (pos>=0) {
          // images can't have children, and there should not be any angle braces 
          // anyhere in the attributes, so should work fine
          nextPos =html.IndexOf(">",pos);

       }

       if (nextPos>0) {
          // back up if XML formed
          if (html.indexOf(nextPos-1,1)=="/") {
            nextPos--;
          }
           // output everything from last position up to but
           // before the closing caret
           sb.Append(html.Substring(lastPos,nextPos-lastPos-1);
           // can't just look for "alt" could be in the image url or class name
           if (html.Substring(pos,nextPos-pos).IndexOf(" alt=\"")<0) {
               sb.Append(" alt="\"\"");
           }
           lastPos=nextPos;
       } else {
           // unclosed image -- just quit
           pos=-1;
       }
    }
    sb.Append(html.Substring(lastPos);
    return sb.ToString();
}
Run Code Online (Sandbox Code Playgroud)

您可能需要在测试、解析或测试变体alt = "(例如,带空格)等之前转换为小写等,具体取决于您对 HTML 的一致性期望。

顺便说一句,这不可能更快,但如果您出于某种原因想使用更通用的东西,您也可以尝试CsQuery。这是我自己的 jQuery 的 C# 实现,它可以非常轻松地执行类似的操作,例如

obj.Select("img").Not("[alt]").Attr("alt",String.Empty);
Run Code Online (Sandbox Code Playgroud)

既然您说 HTML 敏捷包在深度嵌套的 HTML 上表现不佳,那么这可能对您来说效果更好,因为我使用的 HTML 解析器不是递归的,并且无论嵌套如何,都应该线性执行。但它比仅仅根据您的确切需求进行编码要慢得多,因为它当然会将整个文档解析为对象模型。谁知道这对于您的情况是否足够快。