2017-08-25 37 views
2

我正在使用從Web下載的JSON數據。這個JSON的問題是它的內容不正確。在這裏顯示的問題是一個簡單的預覽:修復錯誤的JSON數據

[ 
    { 
    "id": 0, 
    "name": "adsad" 
    }, 
    { 
    "id": "123", 
    "name": "aawew" 
    } 
] 

所以有這些項目,凡在「ID」的一些值是字符串數組和某個地方,這是一個整數。這是我得到的數據,我無法使源代碼修復此問題。

我想出瞭解決的辦法是序列化之前解決這一問題的數據,這裏是我的天真的算法,其中Defaults::intTypes()是所有重要的載體,應該是整數,但有時會串:

void fixJSONData(QString& data) { 
    qDebug() << "Fixing JSON data (thread: " << QThread::currentThreadId() << ")"; 
    QElapsedTimer timer; 
    timer.start(); 

    for (int i = 0; i < data.size(); ++i) { 
     for (const auto& key : Defaults::intTypes()) { 
      if (data.mid(i, key.size() + 3) == "\"" + key + "\":") { 
       int newLine = i + key.size() + 3; 

       while (data[newLine] != ',' && data[newLine] != '}') { 
        if (data[newLine] == '"') { 
         data.remove(newLine, 1); 
        } else { 
         ++newLine; 
        } 
       } 

       i = newLine; 
       break; 
      } 
     } 
    } 
    qDebug() << "Fixing done in " << timer.elapsed() << " ms."; 
} 

那麼它確實解決了這個問題,但算法速度太慢,速度太慢(在390秒內經歷了450萬個字符)。這怎麼能更快地完成?

P.S .:對於JSON序列化我使用nlohmann::json庫。

編輯:在閱讀了一些JSON規則後,它看起來像上面的例子是絕對有效的JSON文件。這應該是一個與C++強類型相關的問題,因此它不能將不同元素的數組序列化爲C++類?

EDIT2:我想從JSON字符串創建爲QVector<Model>其中:

class Model { 
    unsigned id; 
    QString name; 
} 
+1

什麼是與JSON文件中的問題,到底是什麼? 'nlohmann :: json :: parse'似乎正確地處理你的例子。 – Anton

+0

對於'Defaults :: intTypes()'中的每個條目,您的算法幾乎無需每次查看幾乎每行的每個字符。如果您打算假設一行中不超過一個字段名稱,則應該處理每行一次以提取字段名稱(如果有),並查看它是否在整數類型集中。 –

回答

3

雖然有一定改善這種轉換方式的幾個有可能是一個更有效的解決方案。

大多數JSON庫允許最終用戶爲對象定義自定義序列化器/反序列化器。如果您創建了自定義的反序列化器,那麼它可以解析原始數據,而不必修改流或文件。

它不僅更快,而且更優雅。

(如果給定的JSON庫不支持自定義反序列化,我會考慮選擇另一箇中。)

+0

我已經有自定義序列化/反序列化功能。問題是,當試圖從nlohmann :: json創建我的模型類時,我不知道如何處理一個鍵的值可以是2種不同的類型 –

+0

@MarošBeťko您可以使用'json :: get ( )'以整數形式檢索節點的值。無論如何,它應該在反序列化期間完成,而不是在解析之前完成。 – Anton

+0

我不能因爲當它到達「ID」:「123」它拋出錯誤,預計整數。 –