序列化 JSON 数据 Qt.
Serializing JSON data Qt
我正在使用Qt并尝试将以下内容转换为JSON文本,但是当我尝试编译它时,我得到了一个找不到架构错误的符号。
我目前正在使用内置的Qt Json库,因为我不知道如何让QJson工作并静态编译到代码中,以便没有依赖关系。
// Create the message body
QVariantMap message;
message.insert("date", QDate::currentDate().toString());
message.insert("eventType", eventName);
message.insert("payload", messagePayload);
// Initialize the Serializer
QJson::Serializer serializer;
bool ok;
// Serialize the data
QByteArray json = serializer.serialize(message, &ok);
编译器输出如下:
Undefined symbols for architecture x86_64:
"QJson::Serializer::serialize(QVariant const&, bool*)", referenced from:
SWebsocketClient::sendMessage(QString, QMap<QString, QVariant>) in swebsocketclient.o
这是正确的方法,还是有更好的方法?我知道这个问题已经在其他地方被问过,但是其他答案中链接到的大多数文章都不再存在。
您始终可以改用此 JSON 库:
/*
* qvjson.h
*
* Created on: Apr 23, 2010
* Author: drh
*/
#ifndef QVJSON_H_
#define QVJSON_H_
#include <QMap>
#include <QList>
#include <QVariant>
#include <QRegExp>
class QvJson {
public:
QvJson();
virtual ~QvJson();
QVariant parseJson(const QString& jsonString);
// The jsonObject is a QVariant that may be a --
// -- QMap<QString, QVariant>
// -- QList<QVariant>
// -- QString
// -- integer
// -- real number
// -- bool
// -- null (implemented as a QVariant() object)
// Where QVariant appears in the above list, it may recursively
// be one of the above.
QString encodeJson(const QVariant& jsonObject);
private:
enum Error {
ErrorUnrecognizedToken,
ErrorMustBeString,
ErrorMissingColon,
ErrorMissingCommaOrClose,
ErrorNoClosingQuote,
ErrorEndOfInput,
ErrorInvalidNumericValue,
ErrorInvalidHexValue,
ErrorUnrecognizedObject
};
QRegExp mNonBlank;
QRegExp mFindQuote;
QString nextToken(const QString& jsonString, int& position);
QString peekToken(const QString& jsonString, int position);
QVariant parseInternal(const QString& jsonString, int& position, int nesting);
QVariant parseObject(const QString& jsonString, int& position, int nesting);
QVariant parseArray(const QString& jsonString, int& position, int nesting);
QVariant parseString(const QString& jsonString, int& position, int nesting);
QVariant parseBool(const QString& jsonString, int& position, int nesting);
QVariant parseNull(const QString& jsonString, int& position, int nesting);
QVariant parseNumber(const QString& jsonString, int& position, int nesting);
QVariant syntaxError(const QString& method, const QString& jsonString, int position, int nesting, Error error);
QString encodeObject(const QVariant& jsonObject);
QString encodeArray(const QVariant& jsonObject);
QString encodeString(const QVariant& jsonObject);
QString encodeString(const QString& value);
QString encodeNumeric(const QVariant& jsonObject);
QString encodeBool(const QVariant& jsonObject);
QString encodeNull(const QVariant& jsonObject);
QString encodingError(const QString& method, const QVariant& jsonObject, Error error);
};
#endif /* QVJSON_H_ */
/*
* qvjson.cpp
*
* Created on: Apr 23, 2010
* Author: drh
*/
#include "qvjson.h"
#include <QStringList>
#include <QMessageBox>
QvJson::QvJson() {
mNonBlank = QRegExp("\S", Qt::CaseSensitive, QRegExp::RegExp);
mFindQuote = QRegExp("[^\\]"", Qt::CaseSensitive, QRegExp::RegExp);
}
QvJson::~QvJson()
{
// TODO Auto-generated destructor stub
}
QVariant QvJson::parseJson(const QString& jsonString) {
int position = 0;
QVariant result;
result = parseInternal(jsonString, position, 0);
if (result.type() == QVariant::StringList) {
QMessageBox::critical(NULL, "", result.toString());
}
QString token(nextToken(jsonString, position));
if (!token.isEmpty()) {
QMessageBox::critical(NULL, "", QObject::tr("Invalid JSON string -- remaining token %1 at position %2.").arg(token).arg(position));
}
return result;
}
QString QvJson::nextToken(const QString& jsonString, int& position) {
if (position >= jsonString.count()) {
return QString();
}
while (jsonString.at(position) == ' ') {
position++;
if (position >= jsonString.count()) {
return QString();
}
}
if (jsonString.at(position).isLetter()) {
if (position + 4 < jsonString.count()) {
QString word = jsonString.mid(position, 4);
if ((word == "true") || (word == "null")) {
position += 4;
while (position < jsonString.count() && jsonString.at(position) == ' ') {
position++;
}
return word;
}
if ((word == "fals") && (position + 5 < jsonString.count()) && jsonString.at(position + 4) == 'e') {
position += 5;
while (position < jsonString.count() && jsonString.at(position) == ' ') {
position++;
}
return "false";
}
}
}
QString result = QString(jsonString.at(position));
position++;
while (position < jsonString.count() && jsonString.at(position) == ' ') {
position++;
}
return result;
}
// By virtue of its non-& position parm, this method "peeks" at the token without consuming it.
QString QvJson::peekToken(const QString& jsonString, int position) {
return (nextToken(jsonString, position));
}
QVariant QvJson::parseInternal(const QString& jsonString, int& position, int nesting) {
QString token(peekToken(jsonString, position));
QVariant result;
int startPosition = position; // For debug
Q_UNUSED(startPosition);
if (token.isNull()) {
result = syntaxError("parseInternal", jsonString, position, nesting + 1, ErrorEndOfInput);
}
else if (token == "{") {
result = parseObject(jsonString, position, nesting + 1);
}
else if (token == "[") {
result = parseArray(jsonString, position, nesting + 1);
}
else if (token == """) {
result = parseString(jsonString, position, nesting + 1);
}
else if ((token == "true") || (token == "false")) {
result = parseBool(jsonString, position, nesting + 1);
}
else if (token == "null") {
result = parseNull(jsonString, position, nesting + 1);
}
else if ((token == "-") || (token.at(0).isDigit())) {
result = parseNumber(jsonString, position, nesting + 1);
}
else {
result = syntaxError("parseInternal", jsonString, position, nesting + 1, ErrorUnrecognizedToken);
}
return result;
}
QVariant QvJson::parseObject(const QString& jsonString, int& position, int nesting) {
QMap<QString, QVariant> resultObject;
QString token;
int startPosition = position; // For debug
Q_UNUSED(startPosition);
token = nextToken(jsonString, position);
Q_ASSERT(token == "{");
// Handle case of empty object
token = peekToken(jsonString, position);
if (token == '}') {
return QVariant(resultObject);
}
do {
// Next item must be a string
token = peekToken(jsonString, position);
if (token != """) {
return syntaxError("parseObject", jsonString, position, nesting + 1, ErrorMustBeString);
}
QVariant propName;
propName = parseString(jsonString, position, nesting + 1);
// Check for error
if (propName.type() == QVariant::StringList) {
QStringList propNameError(propName.toStringList());
propNameError << QObject::tr("in parseObject(%1,%2)").arg(position).arg(nesting);
return QVariant(propNameError);
}
// Expect a ":"
token = nextToken(jsonString, position);
if (token != ":") {
return syntaxError("parseObject", jsonString, position, nesting + 1, ErrorMissingColon);
}
// Now get the value
QVariant propValue;
propValue = parseInternal(jsonString, position, nesting + 1);
// Check for error
if (propValue.type() == QVariant::StringList) {
QStringList propValueError(propValue.toStringList());
propValueError << QObject::tr("in parseObject(%1,%2)").arg(position).arg(nesting);
return QVariant(propValueError);
}
resultObject[propName.toString()] = propValue;
// Next token must be a "," or "}"
token = nextToken(jsonString, position);
if (token == "}") {
return QVariant(resultObject);
}
else if (token != ",") {
return syntaxError("parseObject", jsonString, position, nesting + 1, ErrorMissingCommaOrClose);
}
} while (true);
}
QVariant QvJson::parseArray(const QString& jsonString, int& position, int nesting) {
QList<QVariant> resultArray;
QString token;
token = nextToken(jsonString, position);
Q_ASSERT(token == "[");
// Handle case of empty object
token = peekToken(jsonString, position);
if (token == ']') {
return QVariant(resultArray);
}
do {
// Get the element of the array
QVariant propValue;
propValue = parseInternal(jsonString, position, nesting + 1);
// Check for error
if (propValue.type() == QVariant::StringList) {
QStringList propValueError(propValue.toStringList());
propValueError << QObject::tr("in parseObject(%1,%2)").arg(position).arg(nesting);
return QVariant(propValueError);
}
resultArray << propValue;
// Next token must be a "," or "]"
token = nextToken(jsonString, position);
if (token == "]") {
return QVariant(resultArray);
}
else if (token != ",") {
return syntaxError("parseArray", jsonString, position, nesting + 1, ErrorMissingCommaOrClose);
}
} while (true);
}
QVariant QvJson::parseString(const QString& jsonString, int& position, int nesting) {
QString result;
// Skip over the double quote character
Q_ASSERT(jsonString.at(position) == '"');
position++;
do {
if (position >= jsonString.count()) {
return syntaxError("parseString", jsonString, position, nesting, ErrorNoClosingQuote);
}
if (jsonString.at(position) == '"') {
break;
}
if (jsonString.at(position) == '') {
position++;
if (position >= jsonString.count()) {
return syntaxError("parseString", jsonString, position, nesting, ErrorNoClosingQuote);
}
switch (jsonString.at(position).unicode()) {
case 'b':
result.append('b');
break;
case 'f':
result.append('f');
break;
case 'n':
result.append('n');
break;
case 'r':
result.append('r');
break;
case 't':
result.append('t');
break;
case 'u':
{
if (position + 4 >= jsonString.count()) {
return syntaxError("parseString", jsonString, position, nesting, ErrorNoClosingQuote);
}
QString hex = jsonString.mid(position + 1, 4);
bool ok;
int value = hex.toInt(&ok, 16);
if (!ok) {
return syntaxError("parseString", jsonString, position+1, nesting, ErrorInvalidHexValue);
}
result.append(QChar(value));
position += 4;
}
default:
result.append(jsonString.at(position));
}
position++;
}
else {
result.append(jsonString.at(position));
position++;
}
} while(true);
Q_ASSERT(jsonString.at(position) == '"');
position++;
return QVariant(result);
}
QVariant QvJson::parseBool(const QString& jsonString, int& position, int nesting) {
bool resultBool;
QString token;
token = nextToken(jsonString, position);
if (token == "true") {
resultBool = true;
}
else if (token == "false") {
resultBool = false;
}
else {
Q_ASSERT(false);
}
return QVariant(resultBool);
}
QVariant QvJson::parseNull(const QString& jsonString, int& position, int nesting) {
QString token;
token = nextToken(jsonString, position);
Q_ASSERT(token == "null");
Q_UNUSED(token);
return QVariant();
}
QVariant QvJson::parseNumber(const QString& jsonString, int& position, int nesting) {
int startPosition = position;
// Allow a leading minus sign
if (jsonString.at(position) == '-') position++;
if (position >= jsonString.count()) {
return syntaxError("parseNumber", jsonString, position, nesting + 1, ErrorEndOfInput);
}
// Allow one or more decimal digits
if (!jsonString.at(position).isDigit()) {
return syntaxError("parseNumber", jsonString, position, nesting + 1, ErrorInvalidNumericValue);
}
while (position < jsonString.count() && jsonString.at(position).isDigit()) {
position++;
}
if (position >= jsonString.count() ||
(jsonString.at(position) != '.' && jsonString.at(position) != 'e' && jsonString.at(position) != 'E')) {
bool ok = false;
int resultInt = jsonString.mid(startPosition, position - startPosition).toInt(&ok);
if (!ok) {
return syntaxError("parseNumber", jsonString, position, nesting + 1, ErrorInvalidNumericValue);
}
return QVariant(resultInt);
}
// Consume any fraction part
if (jsonString.at(position) == '.') {
position++;
while (position < jsonString.count() && jsonString.at(position).isDigit()) {
position++;
}
}
// Consume any exponent part
if (jsonString.at(position) == 'e' || jsonString.at(position) == 'E') {
position++;
// Consume +/- if present
if (jsonString.at(position) == '+' || jsonString.at(position) == '-') {
position++;
}
// Must have at least one digit
if (!jsonString.at(position).isDigit()) {
return syntaxError("parseNumber", jsonString, position, nesting + 1, ErrorInvalidNumericValue);
}
while (position < jsonString.count() && jsonString.at(position).isDigit()) {
position++;
}
}
// Should have a valid floating point value at this point
bool ok = false;
qreal resultReal = jsonString.mid(startPosition, position - startPosition).toDouble(&ok);
if (!ok) {
return syntaxError("parseNumber", jsonString, position, nesting + 1, ErrorInvalidNumericValue);
}
return QVariant(resultReal);
}
QVariant QvJson::syntaxError(const QString& method, const QString& jsonString, int position, int nesting, Error error) {
QString text;
switch (error) {
case ErrorInvalidNumericValue:
text = QObject::tr("Invalid numeric value");
break;
case ErrorInvalidHexValue:
text = QObject::tr("Invalid hex value");
break;
case ErrorEndOfInput:
text = QObject::tr("Unexpected end of input");
break;
case ErrorNoClosingQuote:
text = QObject::tr("No closing quote for literal string");
break;
case ErrorMissingColon:
text = QObject::tr("Missing ':' between attribute name and value");
break;
case ErrorMissingCommaOrClose:
text = QObject::tr("Missing comma, '}', or ']'");
break;
case ErrorMustBeString:
text = QObject::tr("The name of an attribute must be a valid character string");
break;
case ErrorUnrecognizedToken:
text = QObject::tr("The token was not recognized");
break;
default:
Q_ASSERT(false);
}
QString errorMsg = QObject::tr("*** Error %1 in QvJson::%2 at position %3 -- %4").arg(error).arg(method).arg(position).arg(text);
QStringList errorList;
errorList << errorMsg;
return QVariant(errorList);
}
QString QvJson::encodeJson(const QVariant& jsonObject) {
QVariant::Type type = jsonObject.type();
switch (type) {
case QVariant::Map:
return encodeObject(jsonObject);
case QVariant::List:
return encodeArray(jsonObject);
case QVariant::String:
return encodeString(jsonObject);
case QVariant::Int:
case QVariant::Double:
return encodeNumeric(jsonObject);
case QVariant::Bool:
return encodeBool(jsonObject);
case QVariant::Invalid:
return encodeNull(jsonObject);
default:
return encodingError("encodeJson", jsonObject, ErrorUnrecognizedObject);
}
}
QString QvJson::encodeObject(const QVariant& jsonObject) {
QString result("{ ");
QMap<QString, QVariant> map = jsonObject.toMap();
QMapIterator<QString, QVariant> i(map);
while (i.hasNext()) {
i.next();
result.append(encodeString(i.key()));
result.append(" : ");
result.append(encodeJson(i.value()));
if (i.hasNext()) {
result.append(", ");
}
}
result.append(" }");
return result;
}
QString QvJson::encodeArray(const QVariant& jsonObject) {
QString result("[ ");
QList<QVariant> list = jsonObject.toList();
for (int i = 0; i < list.count(); i++) {
result.append(encodeJson(list.at(i)));
if (i+1 < list.count()) {
result.append(", ");
}
}
result.append(" ]");
return result;
}
QString QvJson::encodeString(const QVariant &jsonObject) {
return encodeString(jsonObject.toString());
}
QString QvJson::encodeString(const QString& value) {
QString result = """;
for (int i = 0; i < value.count(); i++) {
ushort chr = value.at(i).unicode();
if (chr < 32) {
switch (chr) {
case 'b':
result.append("\b");
break;
case 'f':
result.append("\f");
break;
case 'n':
result.append("\n");
break;
case 'r':
result.append("\r");
break;
case 't':
result.append("\t");
break;
default:
result.append("\u");
result.append(QString::number(chr, 16).rightJustified(4, '0'));
} // End switch
}
else if (chr > 255) {
result.append("\u");
result.append(QString::number(chr, 16).rightJustified(4, '0'));
}
else {
result.append(value.at(i));
}
}
result.append('"');
QString displayResult = result; // For debug, since "result" often doesn't show
Q_UNUSED(displayResult);
return result;
}
QString QvJson::encodeNumeric(const QVariant& jsonObject) {
return jsonObject.toString();
}
QString QvJson::encodeBool(const QVariant& jsonObject) {
return jsonObject.toString();
}
QString QvJson::encodeNull(const QVariant& jsonObject) {
return "null";
}
QString QvJson::encodingError(const QString& method, const QVariant& jsonObject, Error error) {
QString text;
switch (error) {
case ErrorUnrecognizedObject:
text = QObject::tr("Unrecognized object type");
break;
default:
Q_ASSERT(false);
}
return QObject::tr("*** Error %1 in QvJson::%2 -- %3").arg(error).arg(method).arg(text);
}
相关文章:
- 从数据库实时显示QT c++中的数据
- 如何在Qt中从数据库中检索二进制数据?
- QT QOpenGLWidget:如何在不使用数据块复制的情况下修改VBO中的单个顶点值?
- C++/QT:使用指向私有成员的常量指针作为只读数据共享
- 模拟GPS数据,以便使用Qt与Traccar一起使用
- 如何将 json 数据附加到 Qt 中的现有 json 文件中
- 使用 QT C++过滤大数据的最佳方式
- Qt - 如何将"more"数据写入QProcess?
- libCURL:上传数据崩溃(Qt,SMTP)
- 面临在 if 语句之外打印变量数据的问题 完成使用 Qt 编程
- 将C++数据模型与Qt SCXML状态机一起使用
- Qt - 将空指针(原始数据)转换为 QImage 并将其显示在标签上
- 在QT C++编辑Qtable模型数据时,我需要得到一个小盒子,我需要显示编辑文本,这怎么可能?
- Qt C++ - 如何将数据从工作线程传递到主线程?
- Qt C++ - 如何成功将数据传递给子进程?
- 是否有QT C 数据容器可用于动态大小结构
- 具有两种不同视图的Qt数据模型
- Qt数据报结构结果:混合序列
- 使用foreach循环修改Qt数据结构的正确方法
- Qt数据改变信号-不使用提供的小区范围