我有这样的查询:
/plist/dict[1]/dict/dict/dict/key/following-sibling::dict/string[string()='Algier']
我真正想要选择的是'key'节点(就在follow-sibling :: dict之前)。
xml是这样的:
<?xml version="1.0" encoding="UTF-8"?>
<plist version="1.0">
<dict>
<key>en_GB</key>
<dict>
<key>Africa</key>
<dict>
<key>Algeria</key>
<dict>
<key>60390</key>
<dict>
<key>NAME</key>
<string>Algier</string>
<key>LATITUDE</key>
<string>36.7500</string>
<key>LONGITUDE</key>
<string>3.0500</string>
</dict>
<key>60391</key>
<dict>
<key>NAME</key>
<string>Some other city</string>
<key>LATITUDE</key>
<string>36.7500</string>
<key>LONGITUDE</key>
<string>3.0500</string>
</dict>
</dict>
</dict>
</dict>
</dict>
</plist>
换句话说,我想在城市名称为'Algier'时选择'60390'或在城市名称为'其他城市'时选择60391。
我在QML XmlListModel中执行此操作。
更新了代码 使用QML:
import QtQuick 1.0
Rectangle {
id: container;
width: 360
height: 360
function onLocationModelLoaded(){
console.debug(weLocationModel.count);
}
XmlListModel{
id: weLocationModel;
source: "we_locations.plist";
query: "/*/dict/dict/dict/dict/key[following-sibling::dict[1]/key[.='NAME' and following-sibling::string[1] = 'Algier']]"
XmlRole{
name: "cityId";
query: "name()";
}
onStatusChanged: {
if (status == XmlListModel.Ready){
console.debug("Location Model Ready");
container.onLocationModelLoaded();
}
}
}
}
似乎嵌套的跟随兄弟无法正常工作。 例如:
query: "/*/dict/dict/dict/dict/key[following-sibling::dict[1]/key[.='NAME']]"
这两种情况总是会回归:
Error XPST0003 in file:///Users/Ali/qtprojects/welocationtest-build-simulator/welocationtest.app/Contents/MacOS/welocationtest, at line 2, column 97: syntax error, unexpected ], expecting )
Error XPST0003 in file:///Users/Ali/qtprojects/welocationtest-build-simulator/welocationtest.app/Contents/MacOS/welocationtest, at line 2, column 91: syntax error, unexpected ], expecting end of file
file:///Users/Ali/qtprojects/welocationtest-build-simulator/welocationtest.app/Contents/Resources/qml/welocationtest/main.qml:17:9: QML XmlRole: invalid query: "name()"
Location Model Ready
0
QML是否可能不遵循XPath标准?该解决方案适用于所有其他路径编辑器。
答案 0 :(得分:5)
一个精确选择所需key
元素的XPath表达式是:
/*/dict/dict/dict/dict
/key
[following-sibling::dict[1]/key
[.='NAME'
and
following-sibling::string[1] = $pCity
]
]
当{pmity设置/替换 - "Algier"
时,此XPath表达式选择:
<key>60390</key>
当{pmity设置/替换 - "Some other city"
时,此XPath表达式选择:
<key>60391</key>
基于XSLT的验证:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:param name="pCity" select="'Some other city'"/>
<xsl:template match="/">
<xsl:copy-of select=
"/*/dict/dict/dict/dict
/key
[following-sibling::dict[1]/key
[.='NAME'
and
following-sibling::string[1] = $pCity
]
]
"/>
</xsl:template>
</xsl:stylesheet>
对提供的XML文档应用此转换时:
<plist version="1.0">
<dict>
<key>en_GB</key>
<dict>
<key>Africa</key>
<dict>
<key>Algeria</key>
<dict>
<key>60390</key>
<dict>
<key>NAME</key>
<string>Algier</string>
<key>LATITUDE</key>
<string>36.7500</string>
<key>LONGITUDE</key>
<string>3.0500</string>
</dict>
<key>60391</key>
<dict>
<key>NAME</key>
<string>Some other city</string>
<key>LATITUDE</key>
<string>36.7500</string>
<key>LONGITUDE</key>
<string>3.0500</string>
</dict>
</dict>
</dict>
</dict>
</dict>
</plist>
产生了想要的正确结果:
<key>60391</key>
在上述转换中,我们替换:
<xsl:param name="pCity" select="'Some other city'"/>
<强>与强>:
<xsl:param name="pCity" select="'Algier'"/>
并再次应用转换,然后我们再次获得正确的结果:
<key>60390</key>
答案 1 :(得分:1)
要获取城市的数量,您也可以使用RegEx(特别是如果QML XPath支持不够好):
import QtQuick 1.0
Rectangle {
id: container
width: 360
height: 360
Component.onCompleted: {
loadWeLocationsFile();
}
property string weLocationsXML
signal weLocationsLoaded()
function loadWeLocationsFile() {
// load file
var doc = new XMLHttpRequest();
doc.onreadystatechange = function() {
if (doc.readyState == XMLHttpRequest.DONE) {
// get file content
weLocationsXML = doc.responseText;
// emit signal
weLocationsLoaded();
}
}
doc.open("GET", "we_locations.plist");
doc.send();
}
function getIDByName(name) {
// escape special characters for regex (maybe there is a better way to do this)
var safeName = name.replace(/[-.,?+*#^$()[\]{}\\|]/g, "\\$&");
// create regex
var regex = new RegExp("<key>(.*?)</key>\\s*<dict>\\s*<key>NAME</key>\\s*<string>" + safeName + "</string>", "m");
// execute regex
var match = regex.exec(weLocationsXML);
if (match != null && match.length > 1) {
return match[1]; // name found, group 1 contains id
} else {
return null; // no such name in XML
}
}
// Test it ...
onWeLocationsLoaded: {
console.log("Number for 'Algier':", getIDByName("Algier"));
console.log("Number for 'NotInXML':", getIDByName("NotInXML"));
console.log("Number for 'Some other city':", getIDByName("Some other city"));
}
}
<强>输出:强>
Number for 'Algier': 60390
Number for 'NotInXML': null
Number for 'Some other city': 60391
如果您需要QML模型中的数字,可以创建ListModel
并将数字添加到其中。