QML XmlListModel中的多个嵌套级别

时间:2015-03-21 23:30:26

标签: qml nested

给出以下具有2个嵌套级别的XML源:

<papers>
  <paper id="1">
    <authors>
      <author name="John Doe" />
      <author name="Jane Doe" />
    </authors>
  </paper>
  <paper id="2">
    <authors>
      <author name="John Appleseed" />
    </authors>
  </paper>
</papers>

当我在XmlRole中定义XmlListModel时:

XmlListModel {
  id: myPapers
  source: "http://example.com/papers.xml"
  query: "/papers/paper"
  XmlRole { name: "author"; query: "authors/author/@name/string()" }
}

它将包含所有3位作者,而不仅仅是2&#34; Doe&#34;第一篇论文的作者。我可以在角色中添加一个索引(authors/author[1]),但我现在不知道会有多少论文和作者。定义author1,author2,...,author99并不是一种正确的方法。

如何告诉XmlListModel我只想要ListView中的一篇论文的作者?

ListView {
  model: myPapers 
  delegate: Text { text: author }
}

现在显示:

John Doe
Jane Doe
John Appleseed <-- don't want this one

谢谢!

更新1 源文件是一个网址,我更喜欢多次获取同一个文件来获取数据(这是移动应用的标准) )。

#qt-quick的

更新2 上行告诉我,使用ListView代替Repeater会更好。不知道为什么。相应地修改了问题。

2 个答案:

答案 0 :(得分:3)

进行了更多的挖掘并向更多人提出了问题,最终的答案是:不,这是不可能的标准XmlListModel。你必须推出自己的解决方案。

以下是我未来参考解决方案的片段 - 从Tim Besard的BeTrains.QML代码中借鉴实现:

Item {
    property bool loading: false
    property bool error: false
    property ListModel papers: ListModel{}
    property string source: "http://example.com/papers.xml"

    function fetch() {
        var doc = new XMLHttpRequest();
        doc.onreadystatechange = function() {
            error = false;
            if (doc.readyState === XMLHttpRequest.DONE) {
                if (doc.status != 200) {
                    error = true;
                } else {
                    var rootNode = doc.responseXML.documentElement;
                    parsePapers(rootNode);
                }
                loading = false;
            }
        }
        loading = true;
        doc.open("GET", source);
        doc.send();
    }

    function parsePapers(rootNode) {
        papers.clear();
        for (var i=0; i < rootNode.childNodes.length; ++i) {
            var node = rootNode.childNodes[i];
            if (node.nodeName == "paper") {
                [snip]...[/snip]
            }
        }
    }
}

此解决方案不仅比XmlListModel解决方案更复杂:QML似乎也只具有基本的XML解析器功能。

最后,如果“同一资源的多个HTTP请求”对您无关紧要,您可以使用solution linked by @danielfranca

答案 1 :(得分:1)

通过修改XmlListModelListView的查询,使用@ danielfranca的解决方案:

ListView {
  model: XmlListModel {
    query: "/paper/authors["+(index+1)+"]"
  }
  Text { text: author }
}

这有效,但是......在我的用例中,XML源是一个URL,这意味着这将为每个列表创建另一个HTTP请求。这是不必要的,因为数据已经存在第一个请求。谁有更好的解决方案?