2011-09-24 84 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