Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. QScriptEngine, converting JSON data to QVariants
QtWS25 Last Chance

QScriptEngine, converting JSON data to QVariants

Scheduled Pinned Locked Moved General and Desktop
6 Posts 3 Posters 9.9k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • G Offline
    G Offline
    gallafent
    wrote on last edited by
    #1

    Hi All,

    I'm attempting to read some objects from pre-existing JSON data. I'm running in to trouble when the data is non-trivial. The actual data I need to read is a lot more complex than the samples below, but they demonstrate the problem! I expect this is due to my misreading of the documentation (or misunderstanding of the concepts!) but anyway …

    According to http://doc.qt.nokia.com/4.7/qscriptvalue.html#toVariant , "The array is converted to a QVariantList. Each element is converted to a QVariant, recursively; cyclic references are not followed." - so why when I try to read a simple 2-element array (which I expect to come out as a list) is each element of the QVariantList not the appropriate type of qvariant (string), but instead a "usertype" variant, seemingly with no content?

    With the single string, the output from the code fragment below is:

    valid
    type: QVariant::QString
    "a"

    With the other example data (commented out below), though, an array of two strings, the output is:

    list
    type: QVariant::UserType
    ""
    type: QVariant::UserType
    ""

    (apologies, not quite a complete ready-to-compile sample, lifted from a larger project, but almost complete, just needs the right #includes I think!)

    @void debugPrintVariant (QVariant const & v)
    {
    if (! v. isValid ()) {
    qDebug () << "invalid";
    }
    if (QVariant:: List == v. type ()) {
    qDebug () << "list";
    for (QList <QVariant>:: const_iterator i = v.toList (). begin (); i != v. toList (). end (); ++ i)
    debugPrintVariant (*i);
    } else if (QVariant:: Map == v. type ()) {
    qDebug () << "map";
    for (QMap <QString, QVariant>:: const_iterator i = v. toMap (). begin (); i != v. toMap (). end (); ++ i) {
    qDebug () << "Key: " << i. key ();
    debugPrintVariant (i. value ());
    }
    } else {
    qDebug () << "type: " << v. type ();
    qDebug () << v. toString ();
    }
    }

    void main () {

    // This one works OK
    QString jsonScript = "{"items": "a"}";
    // This one, each list element is "user type", instead of string - how do I get at the data?
    //QString jsonScript = "{"items": ["a", "b"]}";

    QScriptEngine se;
    QScriptValue sv = se.evaluate ("JSON.parse").call(QScriptValue(), QScriptValueList() << jsonScript);
    // Alternative parsing method, same result
    //QScriptValue sv = se. evaluate ("(" + jsonScript + ")");

    QVariant rootVariant = sv. property("items"). toVariant ();

    debugPrintVariant (rootVariant);
    }@

    1 Reply Last reply
    0
    • B Offline
      B Offline
      baysmith
      wrote on last edited by
      #2

      You're iterating over the values wrong. The QVariant::toList() and QVariant::toMap() functions return a new list or map with each call. You can't compare iterators from the first call of toList() with iterators from the second call of toList(). Change it to

      @
      QList<QVariant> list = v.toList();
      for (QList<QVariant>::const_iterator i = list.begin(); i != list.end(); ++i)
      debugPrintVariant(*i);
      @

      or better, use foreach
      @
      foreach (QVariant const &i, v.toList())
      debugPrintVariant(i);
      @

      Nokia Certified Qt Specialist.

      1 Reply Last reply
      0
      • A Offline
        A Offline
        andre
        wrote on last edited by
        #3

        Note that if you just want to parse JSON, you can do so without using QtScript. Take a look at QJSON, for instance.

        1 Reply Last reply
        0
        • G Offline
          G Offline
          gallafent
          wrote on last edited by
          #4

          Thanks for quick and accurate response Bradley, I completely missed that, forgot I was actually transforming the data not just taking a view of it. D'oh.

          Using JSON.parse in this way now works well. Are there any performance or other considerations that mean I should prefer the "JSON.parse" or "QScriptEngine.evaluate" approach?

          1 Reply Last reply
          0
          • A Offline
            A Offline
            andre
            wrote on last edited by
            #5

            [quote author="gallafent" date="1300181725"]Using JSON.parse in this way now works well. Are there any performance or other considerations that mean I should prefer the "JSON.parse" or "QScriptEngine.evaluate" approach?[/quote]
            I seem to remember that the latter is unsafe. It might execute anything, while JSON.parse should be safe. You should not trust the data you get from outside, so just executing it is probably a bad idea. You should check this though, as this is from a vague memory on the topic.

            1 Reply Last reply
            0
            • G Offline
              G Offline
              gallafent
              wrote on last edited by
              #6

              Good point Andre, thanks.

              Much of the data is packaged with the app, and so "safe", but some will indeed come down the wire, so your point about the extra safety provided by using the JSON.parse approach is certainly applicable!

              1 Reply Last reply
              0

              • Login

              • Login or register to search.
              • First post
                Last post
              0
              • Categories
              • Recent
              • Tags
              • Popular
              • Users
              • Groups
              • Search
              • Get Qt Extensions
              • Unsolved