首页 > 解决方案 > Qt 中有哪些工具可以解码 HTML 4 实体?

问题描述

我有一个包含 HTML 4 实体的输入 QString,就像õ我想解码的那样。但我在 Qt 中找不到任何设施可以这样做。Qt有没有办法做到这一点?如果可能的话,我想避免QTextDocument,所以我不必引入 QtGui。

HTML 4 实体在此链接中列出:

https://www.w3schools.com/charsets/ref_html_entities_4.asp

标签: qt

解决方案


出于好奇,我四处看了看。

我发现了这个:如何在 QT 中将实体字符(转义字符)转换为 HTML?. 但是,它使用QTextDocument(这是 GUI 的一部分)OP 想要阻止的内容。

医生。ofQTextDocument::setHtml()没有提及任何具体是否使用可以直接访问的东西(甚至是 Qt 核心的一部分)。因此,我查看了源代码。我从QTextDocument::setHtml()woboq.org开始,然后跟随面包屑。

最后,我结束了qtbase/src/gui/text/qtexthtmlparser.cpp

QString QTextHtmlParser::parseEntity()
{
    const int recover = pos;
    int entityLen = 0;
    QStringRef entity;
    while (pos < len) {
        QChar c = txt.at(pos++);
        if (c.isSpace() || pos - recover > 9) {
            goto error;
        }
        if (c == QLatin1Char(';'))
            break;
        ++entityLen;
    }
    if (entityLen) {
        entity = QStringRef(&txt, recover, entityLen);
        QChar resolved = resolveEntity(entity);
        if (!resolved.isNull())
            return QString(resolved);
        if (entityLen > 1 && entity.at(0) == QLatin1Char('#')) {
            entity = entity.mid(1); // removing leading #
            int base = 10;
            bool ok = false;
            if (entity.at(0).toLower() == QLatin1Char('x')) { // hex entity?
                entity = entity.mid(1);
                base = 16;
            }
            uint uc = entity.toUInt(&ok, base);
            if (ok) {
                if (uc >= 0x80 && uc < 0x80 + (sizeof(windowsLatin1ExtendedCharacters)/sizeof(windowsLatin1ExtendedCharacters[0])))
                    uc = windowsLatin1ExtendedCharacters[uc - 0x80];
                QString str;
                if (QChar::requiresSurrogates(uc)) {
                    str += QChar(QChar::highSurrogate(uc));
                    str += QChar(QChar::lowSurrogate(uc));
                } else {
                    str = QChar(uc);
                }
                return str;
            }
        }
    }
error:
    pos = recover;
    return QLatin1String("&");
}

可以在同一源文件中找到命名实体表:

static const struct QTextHtmlEntity { const char name[9]; quint16 code; } entities[]= {
    { "AElig", 0x00c6 },
    { "AMP", 38 },

...

    { "zwj", 0x200d },
    { "zwnj", 0x200c }
};
Q_STATIC_ASSERT(MAX_ENTITY == sizeof entities / sizeof *entities);

这些对 OP 来说是个坏消息:

  1. 的 APIQTextHtmlParser是私有的:

    //
    //  W A R N I N G
    //  -------------
    //
    // This file is not part of the Qt API.  It exists purely as an
    // implementation detail.  This header file may change from version to
    // version without notice, or even be removed.
    //
    // We mean it.
    //
    
  2. 它是 Qt GUI 的一部分。

如果 OP 坚持要防止 GUI 依赖,我看到的唯一其他机会就是复制代码(或者只是从头开始重新实现它)。


推荐阅读