HTML синтаксический анализатор правильности

Эй, ребята, мне нужно определить, правильно ли задан HTML-документ или нет.
Мне просто нужна простая реализация, использующая только основные классы API Java, т.е. никаких сторонних вещей, таких как JTIDY или что-то в этом роде.

На самом деле, что именно нужно, так это алгоритм, который сканирует список тегов. Если он находит открытый тег, а следующий тег не является его соответствующим закрывающим тегом, то это должен быть другой открытый тег, который в свою очередь должен иметь свой закрывающий тег в качестве следующего тега, а если нет, то это должен быть другой открытый тег, а затем его соответствующий закрывающий тег next и закрывающие теги предыдущих открытых тегов в обратном порядке следуют один за другим в списке. Если список соответствует этому порядку, он возвращает истину или ложь. Я уже написал методы для преобразования тега в закрывающий тег.

Вот скелетный код того, над чем я уже начал работать. Это не слишком аккуратно, но это должно дать вам, ребята, основную идею о том, что я пытаюсь сделать.

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 ответ

Решение

Две мысли Во-первых, может быть, вы могли бы обойтись без использования парсера XML на HTML? Потенциально проще и значительно меньше времени.

Я не слишком много думал об этом, но для меня это звучит как рекурсия и стек - это то, что нужно. Что-то вроде

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;}

*edit 1: вероятно, должен был поместиться в стек.

** редактировать 2: я полагаю, что проблема заключается в том, чтобы определить, где при возврате исключительно логического значения вы остановились. Это потребует некоторого указателя, чтобы вы знали, где вы остановились. Идея, хотя я верю, все еще будет работать.

Другие вопросы по тегам