【问题标题】:Multiple nested levels in a QML XmlListModelQML XmlListModel 中的多个嵌套级别
【发布时间】:2015-03-21 23:30:25
【问题描述】:

给定以下具有 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>

当我在 XmlListModel 中定义 XmlRole 时:

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

它将包含所有 3 位作者,而不仅仅是第一篇论文中的 2 位“Doe”作者。我可以在角色中添加索引 (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

谢谢!

UPDATE 1源文件是一个 URL,我更喜欢 not 多次获取同一个文件以获取数据(它用于移动应用程序)。 p>

UPDATE 2 #qt-quick 上的优势告诉我最好使用ListView 而不是Repeater。还不明白为什么。相应地修改了问题。

【问题讨论】:

  • 从未尝试过,但如果您在查询中添加索引,也许它会起作用?与此处所做的类似:stackoverflow.com/questions/1209382/…
  • 谢谢@danielfranca,请看下面我更长的回复,它有效......但是......

标签: qml nested


【解决方案1】:

做了更多的挖掘和窃听更多的人,最终的答案是:不,这是不可能的标准XmlListModel。您必须推出自己的解决方案。

这是我的解决方案的 sn-p 供将来参考 - 从 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

【讨论】:

    【解决方案2】:

    通过修改ListViewXmlListModel的查询来玩@danielfranca的解决方案:

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-03-05
      • 2020-11-04
      • 1970-01-01
      • 2018-12-22
      • 2017-04-24
      • 2016-05-17
      • 2014-04-04
      • 1970-01-01
      相关资源
      最近更新 更多