QML XmlListModel 中的多个嵌套级别
Multiple nested levels in a QML XmlListModel
给定以下 XML 具有 2 个嵌套级别的源代码:
<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
谢谢!
更新 1 源文件是 URL 我更喜欢 而不是 多次获取同一个文件以获得数据(用于移动应用程序)。
UPDATE 2 #qt-quick 的上行告诉我最好使用 ListView
而不是 Repeater
。还不明白为什么。相应地修改了问题。
通过修改 ListView
中 XmlListModel
的查询来尝试@danielfranca 的解决方案:
ListView {
model: XmlListModel {
query: "/paper/authors["+(index+1)+"]"
}
Text { text: author }
}
这有效,但是...在我的用例中,XML 源是一个 URL,这意味着这将为每个列表创建另一个 HTTP 请求。这是不必要的,因为数据已经存在于第一个请求中。谁有更好的解决方案?
做了更多的挖掘并窃听了更多的人,最后的答案是:不,这是不可能的 标准 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 解析器功能。
最后,如果 "multiple HTTP requests for the same resource" 对你来说不重要,你可以选择 solution linked by @danielfranca。
给定以下 XML 具有 2 个嵌套级别的源代码:
<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
谢谢!
更新 1 源文件是 URL 我更喜欢 而不是 多次获取同一个文件以获得数据(用于移动应用程序)。
UPDATE 2 #qt-quick 的上行告诉我最好使用 ListView
而不是 Repeater
。还不明白为什么。相应地修改了问题。
通过修改 ListView
中 XmlListModel
的查询来尝试@danielfranca 的解决方案:
ListView {
model: XmlListModel {
query: "/paper/authors["+(index+1)+"]"
}
Text { text: author }
}
这有效,但是...在我的用例中,XML 源是一个 URL,这意味着这将为每个列表创建另一个 HTTP 请求。这是不必要的,因为数据已经存在于第一个请求中。谁有更好的解决方案?
做了更多的挖掘并窃听了更多的人,最后的答案是:不,这是不可能的 标准 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 解析器功能。
最后,如果 "multiple HTTP requests for the same resource" 对你来说不重要,你可以选择 solution linked by @danielfranca。