Essentially, the task is to parse the “right” answer and the answer given by the user. As a result, you will obtain two trees that can be compared.
If you're dealing with XHTML, any XML parser in any language will do the trick. If you need to validate HTML which may not necessarily be a valid XML document, then you'll probably need a third-party package which can parse the string and build the DOM from it.
The second step is to compare the two trees. Here, you need to know exactly what should be considered right or wrong. A wrong order of children? Possibly wrong. A wrong order of attributes? That doesn't matter. If you're too strict, the users will be angry at you (“Seriously?! I failed this exercise because I put Hello World!, while Hello, World! with a comma was expected?!”) If you're not strict enough, blatantly wrong answers would eventually be considered right, and users will blame you for teaching them the wrong stuff.
The hard part would be to validate exercises which:
Deal with specific parts of HTML syntax such as comments or CDATA,
Have multiple valid answers (although you shouldn't get too much of that in HTML; in CSS, on the other hand, a lot of problems can be solved using many different solutions),
Make it possible to take some freedom when writing HTML: for instance, if the exercise is to create a
<dl> with the names of different species and their respective description, should it really change my understanding of this feature of HTML if I put an elephant and a horse in the list, instead of a cat and a dog?
This last case is interesting by itself. You may barely validate the schema, while ignoring the actual content. The exercise itself could be something like:
Using only three of the tags you've learned, how can you create a sequence containing three species and showing, for every specie, its name and a short, one-line description? You can't use
use simple regex to parse HTML strings?
Forget about it.