// caller needs to free() the result
WCHAR *HtmlElement::GetAttribute(const char *name) const
{
    for (HtmlAttr *attr = firstAttr; attr; attr = attr->next) {
        if (str::EqI(attr->name, name))
            return DecodeHtmlEntitites(attr->val, codepage);
    }
    return NULL;
}
static void HtmlParser08()
{
    ScopedMem<TCHAR> val(DecodeHtmlEntitites("&auml&test;&&ouml-", CP_ACP));
    assert(str::Eq(val.Get(), _T("\xE4&test;&\xF6-")));
}
inline WCHAR *FromHtmlUtf8(const char *s, size_t len)
{
    ScopedMem<char> tmp(str::DupN(s, len));
    return DecodeHtmlEntitites(tmp, CP_UTF8);
}
static void HtmlParser08()
{
    ScopedMem<WCHAR> val(DecodeHtmlEntitites("&auml&test;&&ouml-", CP_ACP));
    utassert(str::Eq(val, L"\xE4&test;&\xF6-"));
}