> Of course, special characters that are already escaped, i.e. already valid in a text node, don't need to be escaped again.
But this isn't true at all. You could have text that's supposed to look like "<span>" -- just look at the discussion we're having right now. And that text needs to be rendered as "&lt;span&gt;", but it also needs not to be rendered as "&amp;lt;span&amp;gt;". You have to keep track of what you've done to it.
Any decent WYSIWYG editor (which I assume your data is coming from if you're trying to sanitize arbitrary HTML) will render "<span>" as "&lt;span&gt;" in the first place. The sanitizer doesn't need to do anything to it, as the markup is already valid.
You've managed to miss the whole point of the discussion thread and the article above it. Your data is coming from a user. You need to change "<img src onerror=alert(1)>" to "<img src onerror=alert(1)>".
You will not be able to do this if your approach is "doesn't matter; we'll just trust whatever we get".
But this isn't true at all. You could have text that's supposed to look like "<span>" -- just look at the discussion we're having right now. And that text needs to be rendered as "&lt;span&gt;", but it also needs not to be rendered as "&amp;lt;span&amp;gt;". You have to keep track of what you've done to it.