iPhone SDK: загадка XML, после добавления дочернего узла forXPath ничего не возвращает (найдено хакерское решение) - PullRequest
1 голос
/ 10 августа 2011

У меня есть большая загадка,

У меня есть свойство документа Gdataxml:

GDataXMLDocument *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 nodeForXPath]?так что это дурачит меня, что мой документ в порядке, но, возможно, я повредил документ или неверное пространство имен при добавлении удаления некоторых элементов в предыдущем методе?

мой xml начинается так:

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

Обновление

Я только что нашел (хакерское) решение;когда я конвертирую "doc" в NSData с помощью "doc.XMLData", а затем снова конвертирую обратно в doc, тогда это работает!но это не должно быть реальным решением, так как это плохо для преобразования, чтобы получить правильный объект документа.В чем здесь проблема?Я думаю, что это не может исправить пространства имен для нового ребенка.

1 Ответ

1 голос
/ 17 августа 2011

Ваша проблема здесь:

<inferenceresponse xmlns="">

Пустой атрибут пространства имен, очевидно, сбивает с толку оценку XPath libxml. Если вы шагаете по nodesForXPath:namespaces:error: в GDataXMLNode, 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
...