代码之家  ›  专栏  ›  技术社区  ›  Vegar

NSXMLDocument,带有名称空间的nodesForXPath

  •  4
  • Vegar  · 技术社区  · 14 年前

    我想从xml文件中获取一组元素,但是一旦这些元素涉及到名称空间,就失败了。

    这是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>contact@groundspeak.com</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];
    

    有什么线索吗?

    3 回复  |  直到 14 年前
        1
  •  5
  •   user357812 user357812    14 年前

    这个 //cache 指:

    你的 groundspeak:cache 元素位于命名空间URI下 http://www.groundspeak.com/cache/1/0

    因此,如果不能声明名称空间前缀绑定(我认为不能使用cocoa…),可以使用以下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>
    
        2
  •  1
  •   Amy Worrall    13 年前

    您需要向文档的根节点添加新的namespace属性,定义查询子节点时可以使用的前缀:

    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];
    
        3
  •  0
  •   abdollar    14 年前

    //gr公司缓存应该工作。您可能还需要一个名称空间uri设置

    推荐文章