1

我这里有一个很大的谜团,

我有一个 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 中的错误?再次..问题是添加一个新的孩子,它在文档中没有更新,但是当使用相同的 Xpath 查询标准时,我可以在同一根目录下获取其他元素

在 NSlog 中,我可以看到新元素已添加到文档中。

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 时,它就可以工作了!但这不应该是真正的解决方案,来回进行转换以获得正确的文档对象是蹩脚的。这里有什么问题?我猜它不能修复新孩子的命名空间。

4

1 回答 1

1

你的问题在这里:

<inferenceresponse xmlns="">

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

如果您可以控制 XML 的生成,我会得到正确的 XPath 结果,删除了空属性。

<inferenceresponse>

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

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
于 2011-08-17T11:32:07.930 回答