【问题标题】:Parsing HTML tags using Java使用 Java 解析 HTML 标签
【发布时间】:2014-06-06 02:50:05
【问题描述】:

我正在尝试创建一个 HTML 解析器来检查 HTML 标记并验证是否存在与每个打开标记相对应的结束标记。

我现在部分工作,我相信逻辑是正确的,但我在正确获取令牌时遇到问题。当我运行我拥有的代码时,它需要很多空标记,与其他非空标记相比,显然会产生错误。

我想知道如何让它从我的 HTML 文件中读取,但只将内容放入 之间的标记中。我也不希望将任何额外数据(例如 h1 标签之间的文本)考虑在内。

这是一个学校作业,我相信教授希望我们在不使用第三方程序(如 JTidy)的情况下这样做。

非常感谢任何帮助。

import java.util.Scanner;
import java.util.StringTokenizer;
import java.io.*;


public class HTMLDriver
{
   public static void main(String [] args) throws IOException
   {
     // declare variables
     QueueReferenceBased queue = new QueueReferenceBased();

     // Create a scanner object 

     Scanner in = new Scanner(System.in);
     System.out.println("What is your html file name?");
     String fileName = in.next();

     File userFile = new File(fileName);

     if (!userFile.exists())
     {
        System.out.println("File does not exist. This program will now exit.");
        System.exit(0);
     }

    Scanner inputFile = new Scanner(userFile); 
    while (inputFile.hasNext())
    {

        String str = inputFile.nextLine();
        StringTokenizer st = new StringTokenizer(str,"<>");

       //Adds tokens to queue
       while(st.hasMoreTokens())
       {
       String token = st.nextToken();
       Tag t = new Tag(token);
       queue.enqueue(t);
      }
    }   
    //Creates Stack
    StackReferenceBased stack = new StackReferenceBased();

    //Loops through queue if not empty
    while(!queue.isEmpty())
    {
      Object obj = queue.dequeue();
      Tag t2 = (Tag)obj;

        if(t2.getOpen() == true)
        {
           stack.push(t2);
        }

        if(t2.getOpen() == false)
        {
           if(stack.isEmpty())
           {
              System.out.println("There is no match for the " + t2 + " tag");
           }else
           {
              Object obj2 = stack.pop();
              Tag t3 = (Tag)obj2;

              //Make tag class and check equality

              if(t2.getTag().equals(t3.getTag()))
              {
                 System.out.println(t2 + " matches " + t3);
              }else
              {
                 System.out.println("Found " + t2 + " to match " + t3 + " terminating program");
                 System.exit(0);
              }

           }
        }
    }    
  }   
}

【问题讨论】:

    标签: java html html-parsing


    【解决方案1】:

    不要这样做。 Html 在这方面是臭名昭著的。一些标签没有打开/关闭 -- 然后就是所有格式错误的 HTML 和浏览器的怪癖。

    除非您的教授明确禁止您使用 3rd 方库,否则尝试在强大的规模上是疯狂的。在 XML 上,这是可以管理的。

    如果你真的,真的必须自己做,使用正则表达式可以获得不错的结果

    Pattern p = Pattern.compile("<(.*)>") // will get your started. you can then do:
    
    Matcher m = p.matcher();
    m.group( ... ) // this will get you everything between parentheses in the regex 
    

    【讨论】:

    • 我不能再反对了。浏览器使用相同方式的更复杂的过程来解析 HTML,按顺序标记输入流并构建标签标记堆栈。 OP 正在学习这方面的基础知识。在解析 HTML 时,正则表达式是一条死胡同。
    • 我以前从未使用过正则表达式,所以我对如何正确使用有点困惑。我尝试搜索一下教程,但我仍然感到困惑。当我使用您发布的代码时,它给了我一个错误,指出 Matcher m = p.matcher(); 存在错误并且它不能应用于给定的类型。我应该把我的字符串作为参数放在那里吗?我也对 m.group 的工作方式感到困惑。那是我把绳子放进去的地方吗?对不起,如果我看起来很无能,这是我第一次使用正则表达式,它们对我来说有点难。
    • 自己做这件事是死路一条。我说清楚了。如前所述,您可以使用正则表达式获得“可管理”的结果。至于浏览器,任何 Web 开发人员都可以告诉您,每个浏览器都充满了怪癖和错误。它们既可以是复杂的,也可以是错误的。 Litheon,我很高兴提供一些正则表达式指针——给我发消息。我对你最强烈的建议是验证这是你的导师想要的
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-11-14
    • 2016-02-14
    • 2014-04-25
    • 2012-05-26
    • 2011-12-16
    • 2023-03-20
    • 2017-03-19
    相关资源
    最近更新 更多