首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >QML解析XML并将其转换为LisView的ListModel

QML解析XML并将其转换为LisView的ListModel
EN

Stack Overflow用户
提问于 2017-11-01 21:52:16
回答 2查看 2.1K关注 0票数 1

我对Qt和QML很陌生。尽管如此,我正在QML中创建一个可编辑列表,我希望将其导入并导出为XML文件。现在,我不得不从XML文件中导入它,并将其设置为C++端的C++模型。

我希望我可以将XML转换成我希望能够从QML端添加、删除和编辑ListView中的行的表单,因此使用XmlListModel看起来是个坏主意,也就是说,它不提供这些功能。

选择文件位置的main.qml:

代码语言:javascript
运行
复制
    FileDialog {
        id: exportDialog
        title: "Please choose an XML TV file"
        nameFilters: [("*.xml")]

        onAccepted: {
            fileio.parse(importDialog.fileUrl)
        }
        onRejected: {
            console.log("Canceled")
        }
    }

我希望在其中进行转换的C++头文件:

代码语言:javascript
运行
复制
#ifndef FILEIO_H
#define FILEIO_H

#include <QObject>
#include <QFile>
#include <QTextStream>
#include <QXmlStreamReader>
#include <QDebug>

class FileIO : public QObject
{
    Q_OBJECT

public slots:
    bool parse(const QString& source)
    {
        if (source.isEmpty())
            return false;

        QFile file(source);
        if (!file.open(QFile::WriteOnly | QFile::Truncate))
            return false;    

        QFile* mjau = new QFile(source);
        if (!mjau->open(QIODevice::ReadOnly | QIODevice::Text)) {
                printf("Load XML File Problem");
                return false;
        }

        QXmlStreamReader reader(mjau);
        while(!reader.atEnd() && !reader.hasError()) {
            if(reader.readNext() == QXmlStreamReader::StartElement && reader.name() == "parent") {
                 qDebug() << reader.readElementText();
                //printf(reader.readElementText())
            }
        }
    }
public:
    FileIO() {}
};

#endif // FILEIO_H

我想解析的xml文件示例,大量条目:

代码语言:javascript
运行
复制
<notes>
    <note>
        <heading>Help</heading>
        <body>I want to make this work!</body>
    </note>
    <note>
        <heading>Because</heading>
        <body>I love QML <3</body>
    </note>
    ...
</notes>

像这样的事情:

代码语言:javascript
运行
复制
ListModel {
    id: notes
    ListElement {
        heading: "Help"
        body: "I want to make this work!"
    }
    ListElement {
        heading: "Because"
        body: "I love QML <3"
    }
}

现在,当我选择XML文件时,什么都不会发生,但是这个文件被“清除”了,变成了一个空白的.xml文件。我如何正确地解析它,然后将解析的数据转换为QML的ListView ListModel或任何可以支持QML侧编辑的模型?

--更新--对文件的解析将是一个一次性的过程,在解析完之后,我打算使用javascript中的数据,所以如果数据可以在JSON对象结构中被解析,那就太酷了。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-12-04 23:39:38

最后,我使用QDomDocument类读取XML文件,遍历所有节点,并写入我想要的JSON对象的值,如下所示:

代码语言:javascript
运行
复制
QDomElement root = doc.firstChildElement();
QDomNodeList programme = root.elementsByTagName("node");
nodeCollection.push_back(ListElements(program, "title", "lang"));

..。

代码语言:javascript
运行
复制
QJsonObject ListElements (QDomElement root, QString tagname, QString attribute)
{

        QDomNodeList items = root.elementsByTagName(tagname);

        for(int i = 0; i < items.count(); i++)
        {
            QDomNode itemnode = items.at(i);
            if (itemnode.isElement())
            {
                QDomElement itemElement = itemnode.toElement();
                qInfo() << itemElement.tagName(); // <-element name
                qInfo() << itemElement.attribute("lang"); // <-element attribute
                qInfo() << itemElement.text(); // <-element text

// putting the values above inside JSOn object:

                auto nodeData = QJsonObject(
                {
                qMakePair(QString(itemElement.tagName()), QJsonValue(itemElement.text())),
                qMakePair(QString("lang"), QJsonValue(itemElement.attribute("lang"))),
                });

                return nodeData;
            }
        }
    }

所以这个:

代码语言:javascript
运行
复制
  <node>
    <title lang="en">Title1</title>
    <category lang="en">Category1</category>
    <desc lang="en">Description1</desc>
  </node>

变成(这是ListElements返回的内容):

代码语言:javascript
运行
复制
 QJsonObject({"title":"Title1","lang":"en"})
 QJsonObject({"category":"Category1","lang":"en"})
 QJsonObject({"desc":"Description1","lang":"en"})
票数 0
EN

Stack Overflow用户

发布于 2017-11-01 23:10:07

您不应该将其转换为ListModel。相反,实现您自己的具有所需能力的QAbstractListModel的后代。

然而,可能有一个原因,为什么Qt提供的XmlListModel是只读的.因此,如果添加或删除了一个条目,并且该更改不在文件的末尾,则需要复制整个内容。当数据发生变化时,我们需要这样做。对表演不好。

如果你考虑做这样的事情,不要永久地回信。想想看,这是一个很好的时间做回写。一个明显的问题是模型何时被摧毁。但是,由于可能存在一些问题,因此无法正确地销毁对象,因此您可能需要不时保存。

您可以使用计时器来保存,例如更改后的10秒(预期,如果发生了一个更改,那么很快就会发生许多更改)。

您还可以为XML使用一种更复杂的格式,您实际上只是附加了基本记录更改的内容。您不时地对文件进行清理重写,这样就丢失了历史记录,但是这些更改确实应用于xml结构。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47064287

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档