NSXML添加命名空间以使XPath查询起作用

时间:2011-06-26 22:37:47

标签: objective-c xpath xml-namespaces

如果在文档中定义了XMLNS属性,我的问题就是我的XPath查询不起作用。我已经发现这可能是因为所有元素都使用默认的XMLNS,而我的XPath不是。但是,我在NSXML(用于描述和解析XML文档的常见Objective C类系列)中找不到任何合适的方法来解决问题。

例如,如果data不包含XMLNS,则以下代码可以正常工作。如果它的代码如何工作?

NSXMLDocument *xml = [[NSXMLDocument alloc] initWithData:data options:0 error:&error];   
NSArray *result = [xml nodesForXPath:@"/parent/child" error:&error];

1 个答案:

答案 0 :(得分:1)

我刚刚花了一些时间处理类似的问题(谷歌的KML文件)。您的问题可能是由于命名空间问题。设置命名空间映射时,为命名空间指定一个键,然后在XPath表达式中为选择器添加前缀,后跟冒号(:)。此解决方案使用来自整洁TouchXML library的CXMLDocuments和CXMLElements。

首先举一个简单的例子,说你的XML是:

<books xmlns="http://what.com/ever">
  <book>
    <title>Life of Pi</title>
  </book>
  <book>
    <title>Crime and Punishment</book>
  </book
</books>

您可以选择所有图书:

// So, assuming you've already got the data for the XML document
CXMLDocument* xmldoc = [[CXMLDocument alloc] initWithData:xmlDocData options:0 error:nil];
NSDictionary *namespaceMappings = [NSDictionary dictionaryWithObjectsAndKeys:@"http://what.com/ever", @"nskey", nil];
NSError *error = nil;
NSArray *bookElements = [xmldoc nodesForXPath:@"/nskey:books/nskey:book" namespaceMappings:mappings error:&error];

请注意,您需要为每个元素添加前缀,而不仅仅是声明命名空间的元素。