2015-11-03 2 views
1

я сейчас работаю с Xerces 3.1 в Visual Studio 2010.xerces_3_1 adoptNode() возвращает NULL

я написал это (очень простой) кусок кода:

XMLPlatformUtils::Initialize(); 
DOMImplementation* impl = DOMImplementationRegistry::getDOMImplementation(L"XML 1.0"); 

DOMDocument* doc1 = impl->createDocument(L"nsURI", L"abc:root1", 0); 
DOMDocument* doc2 = impl->createDocument(0, L"root2", 0); 
DOMElement* root1 = doc1->getDocumentElement(); 
DOMElement* root2 = doc2->getDocumentElement(); 

DOMElement* el1 = doc1->createElement(L"el1"); 
root1->appendChild(el1); 

DOMNode* tmpNode = doc2->adoptNode(el1); //tmpNode is null after this line 
root2->appendChild(tmpNode); 

doc1->release(); 
doc2->release(); 
xercesc::XMLPlatformUtils::Terminate(); 

Проблема в том , метод adoptNode(...) всегда будет возвращать нулевой указатель, несмотря ни на что. Я действительно не понимаю, что здесь происходит, пожалуйста, помогите мне!

PS: Я знаю, что могу использовать метод importNode(...) и удалять и освобождать старый узел из старого документа, но я надеялся, что был способ исправить мою проблему с помощью adoptNode(...)!

ответ

0

В Xerces API состояния следующих за adoptNode(DOMNode* source):

Изменение ownerDocument узла, его детей, а также присоединенные узлы атрибутов, если таковые имеются.

После некоторого исследования я взглянул на реализацию acceptNode в xerces 3.1, и печальная правда заключается в том, что это невозможно. Цитирование исходного кода:

if(sourceNode->getOwnerDocument()!=this) 
{ 
    // cannot take ownership of a node created by another document, as it comes from its memory pool 
    // and would be delete when the original document is deleted 
    return 0; 
} 

EDIT:

Существует обходной путь для этого метода, но это требует некоторого знания DOM-реализация (особенно при использовании UserData). Вы можете импортировать узел с importNode(...) и удалить другой узел из старого документа.

Старые узлы должны быть выпущены, чтобы не терять память!

Если у вас есть пользовательские данные, прикрепленные к старым узлам, новый документ должен содержать UserDataHandler, который принимает пользовательские данные от старого узла до нового узла!

Обратите внимание, что возможные ссылки на старые узлы теперь не указывают на новые узлы. Их придется изменить вручную (или с помощью некоторого обходного пути UserDataHandler)

Смежные вопросы