iPhone SDK:XML之谜,添加子nodeforXPath后什么都不返回(找到一个hacky解决方案)

时间:2011-08-10 08:19:29

标签: iphone xml xpath gdataxml

我有一个很大的谜,

我有一个Gdataxml文档属性:

GDataXMLDocument *doc;

我正在向doc中添加一个新元素,有趣的是,下面的方法看起来非常适合其他元素,但不适用于我刚添加的元素:

GDataXMLElement *newValueDefElement = [GDataXMLNode elementWithName:@"valuedefinition"];
[variableElement addChild:newValueDefElement];

现在我查询时:

NSString *path = [NSString stringWithFormat:@"//inferenceresponse/state/variable[pageId=%d]/valuedefinition",pageID];       
NSArray *valueElement = [self.doc nodesForXPath:path error:nil];

现在数组带有零对象!找不到新添加的元素!但我可以在调试中看到它作为xml字符串,它究竟怎么找不到我可以看到它在日志上的东西?它是一个缓存问题或命名空间问题或GDataXML中的错误?再次..Problem正在添加一个新的子项,它在某种程度上没有在doc中更新,但是当使用相同的Xpath查询标准时,我可以在同一个根下获取其他元素

在NSlog中我可以看到新元素被添加到doc。

NSData *xmlData2 = self.doc.XMLData;
NSString *s= [[[NSString alloc] initWithBytes:[xmlData2 bytes] length:[xmlData2 length] encoding:NSUTF8StringEncoding] autorelease];
NSLog(s);

另外self.doc.XMLData如何提供与[self.doc nodesForXPath]不同的东西?所以它让我觉得我的文档没问题,但是在添加删除前一个方法中的一些元素的同时,我可能损坏了文档或错误的命名空间?

我的xml像这样开始:

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Header/>
<SOAP-ENV:Body>
<inferenceresponse xmlns="">
<state goalreached="false">
..
..

更新

我刚刚找到了一个(hacky)解决方案;当我用“doc.XMLData”将“doc”转换为NSData然后再转换回doc时,它就可以了!但这不应该是真正的解决方案,来回转换以获得正确的文档对象是蹩脚的。这里有什么问题?我想它无法修复新孩子的命名空间。

1 个答案:

答案 0 :(得分:1)

你的问题在这里:

<inferenceresponse xmlns="">

空命名空间属性显然使libxml XPath评估混乱。如果您单步执行GDataXMLNode的nodesForXPath:namespaces:error:xmlXPathEval确实会返回一个空节点集。

如果您可以控制XML生成,我就会删除正确的XPath结果。

<inferenceresponse>

如果修改服务器响应太难,可以编辑GDataXMLNode.m: 在GDataXMLNode实现中找到方法fixQualifiedNamesForNode:graftingToTreeNode:并替换行

if (foundNS != NULL) {
    // we found a namespace, so fix the ns pointer and the local name

if (foundNS != NULL && foundNS->href != NULL && strlen((char *)foundNS->href) != 0) {
    // we found a namespace, so fix the ns pointer and the local name