После некоторых исследований я нашел следующее решение, которое просто работает как запросы пути NSXMLDocument:
когда XML-документы объявляют пространство имен по умолчанию без префикса, например
xmlns="..."
простые запросы xpaths терпят неудачу, как
xpath: /node
это потому, что xmlXPathEvalExpression
ожидает какой-то префикс пространства имен по умолчанию, но его нет.
Одним из подходов является исправление отсутствующего префикса (как это делает GDataXML), но для этого требуется, чтобы все xpath использовали этот префикс, например
xpath: /__def_ns:node
Но это не то, как работает xpath и NSXMLDocument
.
Следующее решение (на основе DDXMLNode
) отправляется в корневой узел и ищет пространство имен без префикса.
Затем проходят все узлы, указанные ниже, и, если они принадлежат этому пространству имен, он удаляется.
Это так же, как если бы вначале не было пространства имен.
- (void)fixNameSpace
{
xmlNodePtr nodePtr = (xmlNodePtr)self->genericPtr;
xmlNsPtr ns = nodePtr->nsDef;
xmlNsPtr defaultNs = NULL;
while(ns != NULL)
{
if (ns->prefix == NULL)
{
defaultNs = ns;
break;
}
ns = ns->next;
}
if (defaultNs)
[self resetDefaultNs:defaultNs];
}
- (void)resetDefaultNs:(xmlNsPtr)defaultNs
{
xmlNodePtr nodePtr = (xmlNodePtr)self->genericPtr;
xmlNsPtr ns = nodePtr->ns;
if (ns && ns == defaultNs)
xmlSetNs(nodePtr, NULL);
for (NSXMLNode* child in self.children)
[child resetDefaultNs:defaultNs];
}