QDomDocument doc.toString() und die Enkodierung
Verfasst: 2. April 2009 16:07
Mein Problem war/ist dass ich über Sockets von einem Client (Qt) zum Server (C) schicke und eigenartiger weiße immer nur die spitze klammer auf (<) enkodiert, aber nicht die spitze klammer zu (>).
Nach einiger Ursachenforschung bin ich auf folgende Funktion im qt-source gestoßen die dies verursacht:
Alles ist für mich verständlich, aber nicht folgendes segment:
Warum wird die spitze klammer zu nur encodiert wenn davor zwei eckige zu sind?
Nach einiger Ursachenforschung bin ich auf folgende Funktion im qt-source gestoßen die dies verursacht:
Code: Alles auswählen
/* \internal
Encode & escape \a str. Yes, it makes no sense to return a QString,
but is so for legacy reasons.
Remember that content produced should be able to roundtrip with 2.11 End-of-Line Handling
and 3.3.3 Attribute-Value Normalization.
If \a performAVN is true, characters will be escaped to survive Attribute Value Normalization.
If \a encodeEOLs is true, characters will be escaped to survive End-of-Line Handling.
*/
static QString encodeText(const QString &str,
QTextStream &s,
const bool encodeQuotes = true,
const bool performAVN = false,
const bool encodeEOLs = false)
{
#ifdef QT_NO_TEXTCODEC
Q_UNUSED(s);
#else
const QTextCodec *const codec = s.codec();
Q_ASSERT(codec);
#endif
QString retval(str);
int len = retval.length();
int i = 0;
while (i < len) {
const QChar ati(retval.at(i));
if (ati == QLatin1Char('<')) {
retval.replace(i, 1, QLatin1String("<"));
len += 3;
i += 4;
} else if (encodeQuotes && (ati == QLatin1Char('"'))) {
retval.replace(i, 1, QLatin1String("""));
len += 5;
i += 6;
} else if (ati == QLatin1Char('&')) {
retval.replace(i, 1, QLatin1String("&"));
len += 4;
i += 5;
} else if (ati == QLatin1Char('>') && i >= 2 && retval[i - 1] == QLatin1Char(']') && retval[i - 2] == QLatin1Char(']')) {
retval.replace(i, 1, QLatin1String(">"));
len += 3;
i += 4;
} else if (performAVN &&
(ati == QChar(0xA) ||
ati == QChar(0xD) ||
ati == QChar(0x9))) {
const QString replacement(QLatin1String("&#x") + QString::number(ati.unicode(), 16) + QLatin1Char(';'));
retval.replace(i, 1, replacement);
i += replacement.length();
len += replacement.length() - 1;
} else if (encodeEOLs && ati == QChar(0xD)) {
retval.replace(i, 1, QLatin1String("
")); // Replace a single 0xD with a ref for 0xD
len += 4;
i += 5;
} else {
#ifndef QT_NO_TEXTCODEC
if(codec->canEncode(ati))
++i;
else
#endif
{
// We have to use a character reference to get it through.
const ushort codepoint(ati.unicode());
const QString replacement(QLatin1String("&#x") + QString::number(codepoint, 16) + QLatin1Char(';'));
retval.replace(i, 1, replacement);
i += replacement.length();
len += replacement.length() - 1;
}
}
}
return retval;
}Code: Alles auswählen
} else if (ati == QLatin1Char('>') && i >= 2 && retval[i - 1] == QLatin1Char(']') && retval[i - 2] == QLatin1Char(']')) {
retval.replace(i, 1, QLatin1String(">"));
len += 3;
i += 4;
}