16.2.1. Exporting to XML

[ fromfile: memento.xml id: exportcode ]

Example 16.11 shows a reflective recursive toString(), which constructs strings for each of the object's properties and then iterates over the object's children, recursively calling toString() on each child.

Example 16.11. src/libs/dataobjects/qobjectwriter.cpp

[ . . . . ]
QString QObjectWriter::
toString(const QObject* obj, int indentLevel) const {
    QStringList result;
    QString indentspace;
    indentspace.fill(' ', indentLevel * 3 );
    QString className = obj->metaObject()->className();
    QString objectName = obj->objectName();
    QStringList propnames = propertyNames(obj);
    foreach (const QString &propName, propnames) {
        if (propName == "objectName") continue;
        QVariant qv = obj->property(propName.toAscii());

        if (propName == "className") {
               className = qv.toString();
               continue;
        }
        const QMetaObject* meta = obj->metaObject();
        int idx = meta->indexOfProperty(propName.toAscii());
        QMetaProperty mprop = meta->property(idx);

        result <<
        QString("%1  <property name=\"%2\" type=\"%3\" value=\"%4\" />")
            .arg(indentspace).arg(propName).
            arg(qv.typeName()).arg(toString(qv, mprop));
    }
    /* Query over QObjects */
    if (m_children) {
        QList<QObject*> childlist = 
               qFindChildren<QObject*>(obj, QString());

        foreach (const QObject* child, childlist) {
            if (child->parent() != obj) {
      //          qDebug() << "This is not my child!!";
                continue;
            }
            if (child != 0) {
                result << toString(child, indentLevel+1);
            }
        }
    }

    result.insert(0, QString("\n%1<object class=\"%2\" name=\"%3\" >")
        .arg(indentspace).arg(className).arg(objectName));
    result << QString("%1</object>\n").arg(indentspace);
    return result.join("\n");
}
[ . . . . ]

Example 16.11 shows a toString() that uses Qt's properties and QMetaObject facilities to reflect on the class. As it iterates it appends each line to a QStringList. When iteration is complete, the <object> is closed. The returned QString is then produced quickly by calling QStringList::join("\n").