我想实现自动格式化HTML文件的功能。也就是说,能够自动把任意HTML文件格式化为自动缩进的格式,例如:
<HTML>
  <BODY>
    <TABLE>
      <TR>
        <TD>
          <P>
            第一列
          </P>
        </TD>
        ......
      </TR>
      ......
    </TABLE>
  </BODY>
</HTML>为了实现这个功能,必须能够分析HTML文件,取出其中每一个标记,并创建一棵标记树。可是,由于存在单引号和双引号,以及它们的嵌套使用,要实现这个功能就有些困难了。那位高人有比较好的算法?

解决方案 »

  1.   

    好问题,但在未来不一定有很高的价值,不过值得研究
    msn:[email protected]
    我们可以探讨一下。
      

  2.   

    怎么会没有很高的价值呢?举例如下:
    1)具有自动缩进功能的HTML编辑器;
    2)HTML语法检查器;
    3)Spider(用来取得某页面的全部链接后爬行并收集信息);
    ……
      

  3.   

    不知道。我这边有一段分析出Html代码中的图片的函数,给参考一下:
    const
     KeyWord: array[0..1] of String =('background=', 'src=');
     crlf=#13#10;
     .........
    {*********************************************************
     取得HTML代码中图片的路径
     参数 HtmlCode: Html代码
     参数 HtmlImg: 图片路径列表
     *********************************************************}
    procedure GetHTMLImages(var HtmlCode,HtmlImg: TStringList);
    var
      pos1, pos2: Integer;
      tmp1, tmp2: String;
      i: Integer;
    begin
      // 取得HTML文件所有内容文字
      tmp1 := HtmlCode.Text;  //找寻标签的位置
      pos1 := Pos('<', tmp1);
      while pos1>0 do
      begin
        pos2 := Pos('>', tmp1);
        if pos2>pos1 then
        begin
          // 将标签的前後角括号去除
          tmp2 := Copy(tmp1, pos1+1, pos2-pos1-1);      //保存下一个开始搜寻的位置
       pos1 := pos2 + 1;   for i:=0 to 1 do
       begin
        // 搜寻是否有KeyWord阵列中所记录的字串
        pos2 := Pos(KeyWord[i], LowerCase(tmp2));
        if pos2>0 then
        begin
         //取出找到的图片档名字串
         Delete(tmp2, 1, pos2+Length(KeyWord[i])-1);
         tmp2 := (Copy(tmp2, 1, Pos('.', tmp2)+3));     //将档名前多馀的引号去除
         if Length(tmp2)>0 then
          if (tmp2[1]='"') or (tmp2[1]='''') then
            Delete(tmp2, 1, 1);
          // 如果找到的图片档名在HTMLImages中还没有便加入
         pos2 := HtmlImg.IndexOf(tmp2);
         if pos2=-1 then
          HtmlImg.Add(LowerCase(tmp2));
         Break;
        end;
       end;
      end
      else
      begin
       Delete(tmp1, 1, pos2);
       //找下一个标签
       pos1 := Pos('<', tmp1);
       continue;
      end;  Delete(tmp1, 1, pos1);
      //找下一个标签
      pos1 := Pos('<', tmp1);
     end;
    end;
      

  4.   

    谢谢ahpei(独来读网),你的思路跟我一开始的想法完全一致!可是,如果遇到下面的HTML(而且很常见),上面的代码就会出错了,因为无法正确判断出引号里面的"<"和脚本里面的"<":<SCRIPT>
    ......
    if a < b ....
    </SCRIPT>
    <A onClick="if a<b return false">
      

  5.   

    将脚本段分离出来........
    先对纯html分析,而后再在原来位置插入script代码段!参考一下pascal语法分析器的代码!
      

  6.   

    哪里有pascal语法分析器的代码?
      

  7.   

    很大么?不然e-mail一份给我吧。
    [email protected]