HTML格式良好的解析器

时间:2011-03-01 20:15:35

标签: java html-parsing well-formed non-well-formed

Heyy伙计们,我需要确定给定的HTML文档是否格式正确 我只需要一个简单的实现,只使用Java核心API类,即没有第三方的东西,如JTIDY或其他东西。

实际上,究竟需要的是一种扫描TAGS列表的算法。如果它找到一个打开的标签,并且下一个标签不是其对应的关闭标签,那么它应该是另一个开放标签,而后者应该将其关闭标签作为下一个标签,如果不是,则应该是另一个开放标签然后其对应的关闭标记接下来,并且先前打开的标签的关闭标签以相反的顺序在列表上一个接一个地出现。如果列表符合此顺序,则返回true或false。我已经编写了将标签转换为关闭标签的方法。

这是我已经开始研究的骨架代码。它不是太整洁,但它应该给你们一个基本的想法,我正在尝试做什么。

public boolean validateHtml(){

    ArrayList<String> tags = fetchTags();
    //fetchTags returns this [<html>, <head>, <title>, </title>, </head>, <body>, <h1>, </h1>, </body>, </html>]

    //I create another ArrayList to store tags that I haven't found its corresponding close tag yet
    ArrayList<String> unclosedTags = new ArrayList<String>();

    String temp;

    for (int i = 0; i < tags.size(); i++) {

        temp = tags.get(i);

        if(!tags.get(i+1).equals(TagOperations.convertToCloseTag(tags.get(i)))){
            unclosedTags.add(tags.get(i));
            if(){

            }

        }else{
            return true;//well formed html
        }
    }

    return true;
}

1 个答案:

答案 0 :(得分:0)

两个想法。首先,也许你可以在html上使用XML解析器?可能更容易,也更少耗时。

我没有对此进行过多的考虑,但对我来说这听起来像是递归和堆栈将是要走的路。像

这样的东西
public myClass(String htmlInput)
{
    openedTags = new Stack<String>();
    this.htmlInput = htmlInput;
}
public boolean validate()
{
    return validate(this.htmlInput);
}
private boolean validate(String html)
{
    boolean result = true;
    String curTag;
    while(htmlLeft)        //worker loop
    {

        if(isOneOffTag(curTag))                 //matches <tags />
            continue;
        else if(isOpenTag(curTag))              //matches <tags>
        {
            openedTags.push(curTag);
            if(!validate(innerHtml))
                return false;
        }
        else if(isCloseTag(curTag))             //matches </tags>
        {
            String lastTag = (String)openedTags.peek();
            if(!tagIsSimiliar(curTag, lastTag))
                return false;
            openedTags.pop();
        }
    }


    return result;
}
private String nextTag(){return null;}
private boolean isOpenTag(String tag){ return true;}
private boolean isCloseTag(String tag){ return true;}
private boolean isOneOffTag(String tag){ return true;}
private boolean tagIsSimiliar(String curTag, String lastTag){return true;}

*编辑1:可能应该已经推入堆栈。

**编辑2:我想这里的问题是确定何时只返回你已经离开的布尔值。这需要某种指针,以便你知道你在哪里停下来。我认为这个想法仍然可行。