Приветствую. Может кто-нибудь подсказать что не нравится валидатору? Тестовый пример, и остальные какие придумал проходят. Что я не учел?
public static void main(String[] args) throws IOException {
        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
//        String filename = br.readLine();
//        String tag = args[0];
        bufferedReader.close();
        String filename = "d:\\temp.html";
        String tag = "span";
        String openTagSpace = "<" + tag + " ";
        String openTagBlock = "<" + tag + ">";
        String closeTag = "</" + tag + ">";
        int bufSize = closeTag.length();

        // Создаём и заполняем пробелами буффер (очередь)
        Queue<Character> buf = new ArrayBlockingQueue<>(bufSize);
        for (int i = 0; i < bufSize; i++) buf.add(' ');

        // Счетчик для подсчета вложенных тегов.
        int correctTagCount = 0;

        // Вспомогательный массив, для перевода в примитивный тип
        char[] charBuffer = new char[bufSize];

        bufferedReader = new BufferedReader(new FileReader(filename));
        while (bufferedReader.ready()) {
            buf.remove();
            char readedChar = (char) bufferedReader.read();
            buf.add(readedChar);
            if (correctTagCount > 0)
                System.out.print(readedChar);

            // Переводим массив Character в строку. Некрасивый способ, но лучше не нашёл.
            int i = 0;
            for (Character c : buf) charBuffer[i++] = c;
            String strBuffer = String.valueOf(charBuffer);

            // Тут основная логика. Прочитали открывающий тег -- увеличиваем счетчик
            // прочитали закрывающий тег -- уменьшаем счетчик.
            if (strBuffer.endsWith(openTagSpace)) {
                correctTagCount++;
                if (0 == correctTagCount)
                    System.out.print(openTagSpace);
            } else if (strBuffer.endsWith(openTagBlock)) {
                correctTagCount++;
                if (0 == correctTagCount)
                    System.out.print(openTagBlock);
            } else if (strBuffer.endsWith(closeTag)) {
                correctTagCount--;
                if (0 == correctTagCount)
                    // Вот тут спорный момент, нужно ли выводить пустую строку после закрываемого тега.
                    // Формально символы переноса строки уже за пределами тега, но в примере переносы есть.
                    System.out.println();
            }
        }
        bufferedReader.close();
    }