2011-09-24 40 views
3

我有这样的查询:的XPath - 选择节点基于以下同级

/plist/dict[1]/dict/dict/dict/key/following-sibling::dict/string[string()='Algier'] 

我真正想选择的是“关键”节点一个(只以下同胞::字典之前)。

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> 

换句话说,我要选择“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

看起来像QML是越野车和不符合... –

+0

难怪诺基亚现在是它的地方。 :( – zakishaheen

+0

我看了这个,我同意,如果QML在给定的XPath表达式上抛出上面的错误,QML有一个错误。当没有'('?)时,为什么在这个世界中会期待''''?你能提交一个错误报告吗? – LarsH

回答

1

要获取一个城市的数量,您可以使用正则表达式,太(特别是如果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并将编号添加到该编号中。

+0

太棒了。非常感谢 :)。现在解决我的问题。 – zakishaheen

5

,其选择完全相同的通缉key元件一个XPath表达式是本

/*/dict/dict/dict/dict 
    /key 
     [following-sibling::dict[1]/key 
        [.='NAME' 
       and 
        following-sibling::string[1] = $pCity 
        ] 
     ] 

当$ pCity设定/取代由"Algier",这个XPath表达式选择

<key>60390</key> 

当$ pCity设置/替换为"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> 
+0

嗯,听起来很合理。虽然我必须检查它在QML中确实将它标记为正确的答案,我将在此期间进行投票,因为它似乎在其他工具中工作:)谢谢。 – zakishaheen

+1

@debuggerman:不客气。如果QML实现了XPath(它应该),它应该通过这个解决方案产生想要的结果。 –

+0

我更新了更多发现的问题。 – zakishaheen