2010-09-23 80 views
3

我想從xml文件中獲取一組元素,但只要元素涉及命名空間,它就會失敗。NSXMLDocument,nodesForXPath與命名空間

這是XML文件的片段:

<gpx xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
    version="1.0" creator="Groundspeak Pocket Query" 
    xsi:schemaLocation="http://www.topografix.com/GPX/1/0 http://www.topografix.com/GPX/1/0/gpx.xsd http://www.groundspeak.com/cache/1/0 http://www.groundspeak.com/cache/1/0/cache.xsd" 
    xmlns="http://www.topografix.com/GPX/1/0"> 
    <name>My Finds Pocket Query</name> 
    <desc>Geocache file generated by Groundspeak</desc> 
    <author>Groundspeak</author> 
    <email>[email protected]</email> 
    <time>2010-09-15T16:18:55.9846906Z</time> 
    <keywords>cache, geocache, groundspeak</keywords> 
    <bounds minlat="41.89687" minlon="5.561883" maxlat="70.669967" maxlon="25.74735" />  
    <wpt lat="62.244933" lon="25.74735"> 
    <time>2010-01-11T08:00:00Z</time> 
    <name>GC22W1T</name> 
    <desc>Kadonneet ja karanneet by ooti, Traditional Cache (1.5/2)</desc> 
    <url>http://www.geocaching.com/seek/cache_details.aspx?guid=4af28fe9-401b-44df-b058-5fd5399fc083</url> 
    <urlname>Kadonneet ja karanneet</urlname> 
    <sym>Geocache Found</sym> 
    <type>Geocache|Traditional Cache</type> 
    <groundspeak:cache id="1521507" available="True" archived="False" xmlns:groundspeak="http://www.groundspeak.com/cache/1/0"> 
     <groundspeak:name>Kadonneet ja karanneet</groundspeak:name> 
     <groundspeak:placed_by>ooti</groundspeak:placed_by> 
     <groundspeak:owner id="816431">ooti</groundspeak:owner> 
     <groundspeak:type>Traditional Cache</groundspeak:type> 
     <groundspeak:container>Small</groundspeak:container> 
     <groundspeak:difficulty>1.5</groundspeak:difficulty> 
     <groundspeak:terrain>2</groundspeak:terrain> 
     <groundspeak:country>Finland</groundspeak:country> 
     <groundspeak:state> 
     </groundspeak:state> 
     <groundspeak:short_description html="True"> 
     </groundspeak:short_description> 
     <groundspeak:encoded_hints> 
     </groundspeak:encoded_hints> 
     <groundspeak:travelbugs /> 
    </groundspeak:cache> 
    </wpt> 
</gpx> 

我想所有的grounspeak:cache元素,但既不//groundspeak:cache也不//cache似乎任何回報。

NSArray *caches = [self.xml nodesForXPath:@"//cache" error:&error]; 

任何線索?

編輯:有沒有基於可可的軟件在那裏,我可以加載我的xml和測試不同的xpaths?我很新的Objective-C和可可,所以它會很高興檢查它是真的我的Xpath是錯誤的。

回答

5

//cache手段:一個命名空間URI http://www.groundspeak.com/cache/1/0下沒有命名空間下後代元素(或空的命名空間)

groundspeak:cache元素。

因此,如果您不能聲明一個命名空間前綴綁定(我認爲你不能與可可......),你可以使用此XPath表達式:如果你不

//*[namespace-uri()='http://www.groundspeak.com/cache/1/0' and 
    local-name()='cache'] 

想得那麼嚴密的關於命名空間...

//*[local-name()='cache'] 

但這最後是不好的做法,因爲你可能最終會選擇錯誤的節點,因爲使用XML打交道時,你的工具應該支持的命名空間。

爲了證明這一點,這個樣式表:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:template match="/"> 
      <xsl:copy-of select="//*[namespace-uri() = 
            'http://www.groundspeak.com/cache/1/0' and 
            local-name() = 'cache']"/> 
    </xsl:template> 
</xsl:stylesheet> 

輸出:

<groundspeak:cache id="1521507" available="True" archived="False" 
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
      xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
      xmlns="http://www.topografix.com/GPX/1/0" 
      xmlns:groundspeak="http://www.groundspeak.com/cache/1/0"> 
    <groundspeak:name>Kadonneet ja karanneet</groundspeak:name> 
    <groundspeak:placed_by>ooti</groundspeak:placed_by> 
    <groundspeak:owner id="816431">ooti</groundspeak:owner> 
    <groundspeak:type>Traditional Cache</groundspeak:type> 
    <groundspeak:container>Small</groundspeak:container> 
    <groundspeak:difficulty>1.5</groundspeak:difficulty> 
    <groundspeak:terrain>2</groundspeak:terrain> 
    <groundspeak:country>Finland</groundspeak:country> 
    <groundspeak:state></groundspeak:state> 
    <groundspeak:short_description html="True"></groundspeak:short_description> 
    <groundspeak:encoded_hints></groundspeak:encoded_hints> 
    <groundspeak:travelbugs /> 
</groundspeak:cache> 
+0

它們都沒有返回任何元素: -/ – Vegar 2010-09-24 06:01:11

+0

@Vegar:真奇怪!兩者都適用於我的文檔作爲輸入。 – 2010-09-24 12:06:30

+0

它可以在樣式錶轉換中工作,還是可以作爲nodesForXPath :: method的輸入工作? – Vegar 2010-09-29 09:04:46

0

// groundspeak:緩存應該工作。您可能需要一個命名空間URI的設置以及

+1

以及如何指定namespace-uri設置? – Vegar 2010-09-24 05:55:16

1

你需要一個新的命名空間屬性添加到您的文檔的根節點,定義一個前綴,您可以使用時查詢孩子:

NSXMLDocument *xmldoc = ... 
NSXMLElement *namespace = [NSXMLElement namespaceWithName:@"mns" stringValue:@"http://mynamespaceurl.com/mynamespace"]; 
[xmldoc.rootElement addNamespace:namespace]; 

然後當你查詢事情後,你可以使用該前綴引用命名空間:

NSArray * caches = [xmldoc.rootElement nodesForXPath:@"//mns:caches" error:&error];